繁体   English   中英

SQL-仅选择某些行(如果存在)

[英]SQL - selecting only certain rows if they exist

我有一个包含家庭住址和邮寄地址的表。 看起来像这样:

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

我需要编写一条SQL语句,如果存在,它将仅返回邮寄地址(MLG记录),否则,将返回家庭地址(HOM记录)。

该表的预期结果将是:

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

您能提供的任何帮助将不胜感激! 谢谢!

使用相关子查询

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

如果您使用的是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

这可以通过使用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  |

在数据库小提琴上查看

这是一个优先级查询。 对于两个值,通常最简单的方法是not exists (或not in not exists )的union allunion all

对于一般case ,使用row_number()比较方便:

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使用order by type desc ,因为这两种类型恰好以相反的字母顺序排序。 但是,我建议使用case因为其意图更为明确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM