MySQL Select 默认是最后的手段
MySQL Select where default is last resort
我正在尝试加入 table 并按一列和分组进行排序。我正在尝试 select 以 CU 开头的 CUID 超过 DEFAULT 值。我已经阅读了 Whosebug 上发布的答案,看起来我做的事情是正确的。我认为这可能只是我缺少的一些小东西。我认为由于插入顺序,order by 不起作用。我想查询使用 DEFAULT 作为最后一个选项。
SELECT A.*, B.value, B.CUID
FROM A
JOIN B
ON A.ID = B.SettingID
WHERE B.CUID = 'CU1' OR B.CUID = 'DEFAULT'
GROUP BY ID
ORDER BY CUID ASC
在朋友的帮助下,发现这只在某些时候有效,因为插入顺序,并且只有 B.CUID 按字母顺序排列在 'DEFAULT' 之后。
Table一个
| id | Name |
| 1 | blah |
| 2 | was |
| 3 | here |
Table B
| ID | SettingID | Value | CUID |
| 1 | 1 | a | CU1 |
| 2 | 2 | b | CU1 |
| 3 | 1 | c | DEFAULT |
| 4 | 2 | d | DEFAULT |
| 5 | 3 | e | DEFAULT |
没有 GROUP BY 的结果
| SettingID | Name | Value | CUID |
| 1 | blah | a | CU1 |
| 2 | was | b | CU1 |
| 1 | blah | c | DEFAULT |
| 2 | was | d | DEFAULT |
| 3 | here | e | DEFAULT |
GROUP BY
后的结果
| SettingID | Name | Value | CUID |
| 1 | blah | c | DEFAULT |
| 2 | was | d | DEFAULT |
| 3 | here | e | DEFAULT |
预期结果
| SettingID | Name | Value | CUID |
| 1 | blah | a | CU1 |
| 2 | was | b | CU1 |
| 3 | here | e | DEFAULT |
你可以用 EXISTS
来做,这样对于每个 SettingID
你都会得到以 'CU'
开头的 CUID
的行,或者如果它不存在那么您得到具有替代值的行:
SELECT a.*, b.value, b.CUID
FROM TableA a
INNER JOIN (
SELECT b1.*
FROM TableB b1
WHERE b1.CUID LIKE 'CU%'
OR NOT EXISTS (
SELECT 1
FROM TableB b2
WHERE b2.SettingID = b1.SettingID AND b2.CUID LIKE 'CU%'
)
) b ON b.SettingID = a.id
如果你的MySql版本是8.0+,你可以在tableTableB
中使用ROW_NUMBER()
window函数获取首选行:
SELECT a.*, b.value, b.CUID
FROM TableA a
INNER JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY SettingID ORDER BY CUID LIKE 'CU%' DESC) rn
FROM TableB
) b ON b.SettingID = a.id
WHERE b.rn = 1
参见demo。
The table can have a DEFAULT setting and any other CUID Setting. There will only be one other.
我会用
SELECT b1.SettingID,
a.name,
COALESCE(b2.value, b1.value) AS value,
COALESCE(b2.CUID, b1.CUID) AS CUID
FROM a
JOIN b AS b1 on a.id = b1.SettingID
LEFT JOIN b AS b2 ON a.id = b2.SettingID
AND b2.CUID != 'DEFAULT'
WHERE b1.CUID = 'DEFAULT'
如果每个 SettingID
可能有多个 'DEFAULT'
,则添加 DISTINCT
。
我正在尝试加入 table 并按一列和分组进行排序。我正在尝试 select 以 CU 开头的 CUID 超过 DEFAULT 值。我已经阅读了 Whosebug 上发布的答案,看起来我做的事情是正确的。我认为这可能只是我缺少的一些小东西。我认为由于插入顺序,order by 不起作用。我想查询使用 DEFAULT 作为最后一个选项。
SELECT A.*, B.value, B.CUID
FROM A
JOIN B
ON A.ID = B.SettingID
WHERE B.CUID = 'CU1' OR B.CUID = 'DEFAULT'
GROUP BY ID
ORDER BY CUID ASC
在朋友的帮助下,发现这只在某些时候有效,因为插入顺序,并且只有 B.CUID 按字母顺序排列在 'DEFAULT' 之后。
Table一个
| id | Name |
| 1 | blah |
| 2 | was |
| 3 | here |
Table B
| ID | SettingID | Value | CUID |
| 1 | 1 | a | CU1 |
| 2 | 2 | b | CU1 |
| 3 | 1 | c | DEFAULT |
| 4 | 2 | d | DEFAULT |
| 5 | 3 | e | DEFAULT |
没有 GROUP BY 的结果
| SettingID | Name | Value | CUID |
| 1 | blah | a | CU1 |
| 2 | was | b | CU1 |
| 1 | blah | c | DEFAULT |
| 2 | was | d | DEFAULT |
| 3 | here | e | DEFAULT |
GROUP BY
后的结果| SettingID | Name | Value | CUID |
| 1 | blah | c | DEFAULT |
| 2 | was | d | DEFAULT |
| 3 | here | e | DEFAULT |
预期结果
| SettingID | Name | Value | CUID |
| 1 | blah | a | CU1 |
| 2 | was | b | CU1 |
| 3 | here | e | DEFAULT |
你可以用 EXISTS
来做,这样对于每个 SettingID
你都会得到以 'CU'
开头的 CUID
的行,或者如果它不存在那么您得到具有替代值的行:
SELECT a.*, b.value, b.CUID
FROM TableA a
INNER JOIN (
SELECT b1.*
FROM TableB b1
WHERE b1.CUID LIKE 'CU%'
OR NOT EXISTS (
SELECT 1
FROM TableB b2
WHERE b2.SettingID = b1.SettingID AND b2.CUID LIKE 'CU%'
)
) b ON b.SettingID = a.id
如果你的MySql版本是8.0+,你可以在tableTableB
中使用ROW_NUMBER()
window函数获取首选行:
SELECT a.*, b.value, b.CUID
FROM TableA a
INNER JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY SettingID ORDER BY CUID LIKE 'CU%' DESC) rn
FROM TableB
) b ON b.SettingID = a.id
WHERE b.rn = 1
参见demo。
The table can have a DEFAULT setting and any other CUID Setting. There will only be one other.
我会用
SELECT b1.SettingID,
a.name,
COALESCE(b2.value, b1.value) AS value,
COALESCE(b2.CUID, b1.CUID) AS CUID
FROM a
JOIN b AS b1 on a.id = b1.SettingID
LEFT JOIN b AS b2 ON a.id = b2.SettingID
AND b2.CUID != 'DEFAULT'
WHERE b1.CUID = 'DEFAULT'
如果每个 SettingID
可能有多个 'DEFAULT'
,则添加 DISTINCT
。