我有一个包含家庭住址和邮寄地址的表。看起来像这样:
es5
我需要编写一条SQL语句,该语句仅返回邮寄地址(MLG记录)(如果存在),否则将返回家庭地址(HOM记录)。
此表的预期结果将是:
ID Name StNum StName City State Zip Type
-- ---- ----- ------ ---- ----- --- ----
1 Joe 1234 Main St Waco TX 76767 HOM
1 Joe 2345 High St Waco TX 76763 MLG
2 Amy 3456 Broad St Athens GA 34622 HOM
3 Mel 987 Front St Cary NC 65331 HOM
3 Mel 1111 Main Ave Hilo HI 99779 MLG
您能提供的任何帮助将不胜感激!谢谢!
答案 0 :(得分:1)
使用相关子查询
select * from
(
select *,case when Type='MLG' then 1 else 0 end as typeval
from tablename
)A where typeval in (select max(case when Type='MLG' then 1 else 0 end) from tablename b
where a.name=b.name)
或者,如果您的数据库支持row_number()
,那么您可以在下面尝试-
select * from
(
select *, row_number() over(partition by name order by case when Type='MLG' then 1 else 0 end desc)
from tablename
)A where rn=1
答案 1 :(得分:0)
如果您使用的是SQL Server,我可以使用ROW_NUMBER函数来解决。
SELECT ID, Name, StNum, StName, City, State, Zip, Type
FROM (
SELECT *
,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Type DESC) AS Rn
FROM yourtable
)
WHERE Rn = 1
答案 2 :(得分:0)
这可以使用WHERE
子句来完成,该子句排除具有MLG的用户的ID
模式(MySQL v5.7)
CREATE TABLE test (
`ID` INTEGER,
`Name` VARCHAR(3),
`StNum` INTEGER,
`StName` VARCHAR(8),
`City` VARCHAR(6),
`State` VARCHAR(2),
`Zip` INTEGER,
`Type` VARCHAR(3)
);
INSERT INTO test
(`ID`, `Name`, `StNum`, `StName`, `City`, `State`, `Zip`, `Type`)
VALUES
('1', 'Joe', '1234', 'Main St', 'Waco', 'TX', '76767', 'HOM'),
('1', 'Joe', '2345', 'High St', 'Waco', 'TX', '76763', 'MLG'),
('2', 'Amy', '3456', 'Broad St', 'Athens', 'GA', '34622', 'HOM'),
('3', 'Mel', '987', 'Front St', 'Cary', 'NC', '65331', 'HOM'),
('3', 'Mel', '1111', 'Main Ave', 'Hilo', 'HI', '99779', 'MLG');
查询#1
SELECT id,
name,
StNum,
StName,
City,
State,
Zip,
Type
FROM test t1
WHERE t1.`Type` = 'MLG'
OR t1.id NOT IN
(
SELECT id
FROM test t2
WHERE t2.`Type` = 'MLG'
);
输出:
| id | name | StNum | StName | City | State | Zip | Type |
| --- | ---- | ----- | -------- | ------ | ----- | ----- | ---- |
| 1 | Joe | 2345 | High St | Waco | TX | 76763 | MLG |
| 2 | Amy | 3456 | Broad St | Athens | GA | 34622 | HOM |
| 3 | Mel | 1111 | Main Ave | Hilo | HI | 99779 | MLG |
或者,我的第一个哑巴版本:
可以使用UNION
模式(MySQL v5.7)
CREATE TABLE test (
`ID` INTEGER,
`Name` VARCHAR(3),
`StNum` INTEGER,
`StName` VARCHAR(8),
`City` VARCHAR(6),
`State` VARCHAR(2),
`Zip` INTEGER,
`Type` VARCHAR(3)
);
INSERT INTO test
(`ID`, `Name`, `StNum`, `StName`, `City`, `State`, `Zip`, `Type`)
VALUES
('1', 'Joe', '1234', 'Main St', 'Waco', 'TX', '76767', 'HOM'),
('1', 'Joe', '2345', 'High St', 'Waco', 'TX', '76763', 'MLG'),
('2', 'Amy', '3456', 'Broad St', 'Athens', 'GA', '34622', 'HOM'),
('3', 'Mel', '987', 'Front St', 'Cary', 'NC', '65331', 'HOM'),
('3', 'Mel', '1111', 'Main Ave', 'Hilo', 'HI', '99779', 'MLG');
查询#1
SELECT id,
name,
StNum,
StName,
City,
State,
Zip,
Type
FROM test t1
WHERE t1.`Type` = 'MLG'
UNION ALL
SELECT id,
name,
StNum,
StName,
City,
State,
Zip,
Type
FROM test t2
WHERE t2.id NOT IN (SELECT id FROM test t3 WHERE t3.`Type` = 'MLG')
ORDER BY id;
输出
| id | name | StNum | StName | City | State | Zip | Type |
| --- | ---- | ----- | -------- | ------ | ----- | ----- | ---- |
| 1 | Joe | 2345 | High St | Waco | TX | 76763 | MLG |
| 2 | Amy | 3456 | Broad St | Athens | GA | 34622 | HOM |
| 3 | Mel | 1111 | Main Ave | Hilo | HI | 99779 | MLG |
答案 3 :(得分:0)
如果您使用的是SQL Server
,则使用WITH TIES
的另一种方式如下。
select top (1) with ties *
from YourTableName
order by row_number() over(partition by id order by type desc)
答案 4 :(得分:0)
这是一个优先级查询。具有两个值的通常最简单的方法是将union all
(或not exists
)与not in
一起使用。
那不能很好地概括。对于更多的值,将row_number()
与case
一起使用很方便:
select t.*
from (select t.*,
row_number() over (partition by id
order by (case when type = 'MLG' then 1 else 2 end)
) as seqnum
from t
) t
where seqnum = 1;
在您的特定情况下,您可以使用order by type desc
,因为这两种类型恰好以相反的字母顺序排列。但是,我建议使用case
,因为其意图更为明确。