Postgres查询根据行数和存在

时间:2015-04-25 04:53:01

标签: sql database postgresql

这听起来可能很复杂,所以请耐心等待。 :)

我有两个表:usersprofiles。用户可以拥有许多配置文件,这些配置文件在用户OAuth进入Facebook或Google等提供商时填写。 profiles有一个source名称的列,例如' Google'或者' Facebook'以及包含个人资料公开image_url的列。

如果用户具有关联的个人资料,当我在网页上的列表中显示用户时,我想在image_url标记中使用img。如果用户有多个配置文件,我希望比谷歌更喜欢Facebook图像。

因此,对于所有用户,我希望获得正确的image_url以及其他user.*属性。我可以在一个Postgres查询中完全执行此操作吗?如果是这样,它会是什么样子?

到目前为止(令人尴尬),我所拥有的只是:

select image_url from users join profiles on users.id = profiles.user_id;

如果用户连接了多个配置文件,这将为我提供多行。我想修改此查询,以便:

  • 没有相关个人资料的用户应null
  • image_url
  • 只有关联的Google个人资料的用户应该拥有该Google个人资料中的图片网址
  • 只有相关联的Facebook个人资料的用户应该拥有该Facebook个人资料中的图片网址
  • 同时拥有相关联的Facebook个人资料和Google个人资料的用户应具有Facebook图片网址

任何SQL专家都可以权衡吗?谢谢!

澄清:

  • 个人资料只能来自Facebook或Google。用户只能拥有1个Facebook个人资料和/或1个Google个人资料。 (也就是说,用户不能拥有多个Google个人资料,也不能拥有多个Facebook个人资料。)

1 个答案:

答案 0 :(得分:1)

优雅的解决方案将使用两个CTE和一个#include <iostream> #include <iomanip> using namespace std; long double getUserInput() { cout << "Please enter a number: \n"; long double x; cin >> x; return x; } char getMathematicalOperation() { cout << "Please enter which operator you want " "(add +, subtract -, multiply *, or divide /): \n"; char o; cin >> o; return o; } long double calculateResult(long double nX, char o, long double nY) { // note: we use the == operator to compare two values to see if they are equal // we need to use if statements here because there's no direct way // to convert chOperation into the appropriate operator if (o == '+') // if user chose addition return nX + nY; // execute this line if (o == '-') // if user chose subtraction return nX - nY; // execute this line if (o == '*') // if user chose multiplication return nX * nY; // execute this line if (o == '/') // if user chose division return nX / nY; // execute this line return -1; // default "error" value in case user passed in an invalid chOperation } void printResult(long double x) { cout << "The answer is: " << setprecision(0.01) << x << "\n"; } long double calc() { // Get first number from user long double nInput1 = getUserInput(); // Get mathematical operations from user char o = getMathematicalOperation(); // Get second number from user long double nInput2 = getUserInput(); // Calculate result and store in temporary variable (for readability/debug-ability) long double nResult = calculateResult(nInput1, o, nInput2); // Print result printResult(nResult); return 0; }

COALESCE

第一个CTE获得Facebook image_url,如果可用,第二个CTE获得Google image_url。 WITH fb AS ( SELECT user_id, image_url FROM profiles WHERE profile = 'Facebook' ), ggl AS ( SELECT user_id, image_url FROM profiles WHERE profile = 'Google' ) SELECT users.*, COALESCE(fb.image_url, ggl.image_url) FROM users LEFT JOIN ggl ON ggl.user_id = users.id LEFT JOIN fb ON fb.user_id = users.id 确保选择Facebook image_url(如果存在)。