0

首先这只是一个测试表,我想学习一些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');
4

1 回答 1

0

可能有更有效的方法。以下查询在子查询中计算 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

使用“限制”是为了以防万一数据中有多个彼得。

您还可以使用“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 子句中的子查询将(可能)在每一行上进行评估。

于 2012-08-08T13:42:02.843 回答