【问题标题】:sql compare dynamic count valuesql比较动态计数值
【发布时间】:2012-08-08 12:14:41
【问题描述】:

首先这只是一个测试表,我想学习一些 sql 查询。 我想知道谁和“彼得”一样经常预订同一航班(从慕尼黑开始)。 给我正确结果的查询是:

SELECT r1.vorname
FROM (
SELECT p1.vorname, count(p1.passnr) as anzahl
FROM passagier p1, teilnehmer t1, abflug a
WHERE a.abflug = 'münchen'
AND t1.flugnr = a.flugnr
AND t1.passnr = p1.passnr
group by p1.passnr ) as r1,
(
SELECT p1.vorname, count(p1.passnr) as anzahl
FROM passagier p1, teilnehmer t1, abflug a
WHERE a.abflug = 'münchen'
AND t1.flugnr = a.flugnr
AND t1.passnr = p1.passnr
group by p1.passnr ) as r2

WHERE r2.vorname = 'peter'
AND r1.vorname != 'peter'
AND r1.anzahl = r2.anzahl

有没有更好的查询来获得相同的结果?

--
-- Table structure for table `abflug`
--

CREATE TABLE IF NOT EXISTS `abflug` (
  `flugnr` varchar(30) NOT NULL,
  `zielkrz` varchar(30) NOT NULL,
  `ziel` varchar(30) NOT NULL,
  `abflkrz` varchar(30) NOT NULL,
  `abflug` varchar(30) NOT NULL,
  PRIMARY KEY (`flugnr`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `abflug`
--

INSERT INTO `abflug` (`flugnr`, `zielkrz`, `ziel`, `abflkrz`, `abflug`) VALUES
('ba921', 'fra', 'frankfurt', 'muc', 'münchen'),
('lh807', 'nrt', 'tokyo narita', 'fra', 'frankfurt'),
('lh808', 'fra', 'frankfurt', 'kix', 'osaka kansai'),
('lh809', 'kix', 'osaka kansai', 'fra', 'frankfurt');


--
-- Table structure for table `passagier`
--

CREATE TABLE IF NOT EXISTS `passagier` (
  `passnr` varchar(30) NOT NULL,
  `vorname` varchar(30) NOT NULL,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`passnr`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `passagier`
--

INSERT INTO `passagier` (`passnr`, `vorname`, `name`) VALUES
('10118', 'gerhard', 'schröder'),
('10120', 'peter', 'müller'),
('10123', 'angela', 'merkel'),
('10999', 'aryan', 'layes'),
('11000', 'jessica', 'alba');

--
-- Table structure for table `teilnehmer`
--

CREATE TABLE IF NOT EXISTS `teilnehmer` (
  `flugnr` varchar(30) NOT NULL,
  `passnr` varchar(30) NOT NULL,
  `datum` varchar(30) NOT NULL,
  PRIMARY KEY (`flugnr`,`passnr`,`datum`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `teilnehmer`
--

INSERT INTO `teilnehmer` (`flugnr`, `passnr`, `datum`) VALUES
('ba921', '10120', '20.1.2012'),
('ba921', '10120', '23.1.2012'),
('ba921', '10123', '20.1.2012'),
('ba921', '10999', '20.1.2012'),
('ba921', '10999', '23.1.2012'),
('ba921', '11000', '23.1.2012'),
('lh807', '10118', '20.1.2012'),
('lh807', '10120', '20.1.2012'),
('lh807', '10123', '20.1.2012'),
('lh808', '10118', '27.3.2012'),
('lh808', '10120', '23.1.2012'),
('lh808', '10123', '23.1.2012'),
('lh809', '10120', '23.1.2012');

【问题讨论】:

    标签: mysql sql database count compare


    【解决方案1】:

    可能有更有效的方法。以下查询在子查询中计算 Peter 的信息,并将其连接到查询的其余部分:

    select allp.*
    from (SELECT p.passnr, count(p1.passnr) as anzahl
          FROM passagier p join
               teilnehmer t
               on t.passnr = p.passnr join
               abflug a
               on t.flugnr = a.flugnr
          where a.abflug = 'münchen'
          group by p.passnr
         ) allp cross join
         (SELECT count(p1.passnr) as anzahl
          FROM passagier p join
               teilnehmer t
               on t.passnr = p.passnr join
               abflug a
               on t.flugnr = a.flugnr 
          where a.abflug = 'münchen' AND
                p.vorname = 'peter'
          limit 1
         ) peter
    where allp.forname <> 'peter' and allp.anzahl >= peter.anzahl
    

    使用“limit”是为了防止数据中有多个彼得。

    您也可以使用“with”语句来简化:

    with allp as (
          SELECT count(p1.passnr) as anzahl
          FROM passagier p join
               teilnehmer t
               on t.passnr = p.passnr join
               abflug a
               on t.flugnr = a.flugnr 
          where a.abflug = 'münchen'
         ) allp 
    select *
    from allp
    where allp.forname <> 'peter' and
          allp.anzahl >= (select anzahl from allp where vorname = 'peter' limit 1)
    

    此版本按乘客汇总了所有数据。然后它选择“anzahl”大于彼得的那些。在 mysql 中,第一个版本可能会执行得更好,因为 WHERE 子句中的子查询将(可能)在每一行上进行评估。

    【讨论】:

      猜你喜欢
      • 2016-03-02
      • 1970-01-01
      • 2016-03-03
      • 2011-05-11
      • 2018-11-03
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 1970-01-01
      相关资源
      最近更新 更多