如何解决此(SQL)查询?

时间:2015-04-23 19:31:31

标签: sql oracle sqlplus

这可能是有史以来最简单的查询之一,我可能只是让它变得更难,但我需要它完成。

所以,有三个表:

TABLE AGENT
(
A_ID INTEGER PRIMARY KEY,
A_NAME VARCHAR(20) NOT NULL,
A_ADDR VARCHAR(30) NOT NULL,
A_PHN CHAR(14) NOT NULL,
A_EMAIL VARCHAR(20) NOT NULL);
)

TABLE E_TRANSACTION
(
T_ID INTEGER PRIMARY KEY,
T_AMT FLOAT NOT NULL,
T_DATE DATE NOT NULL,
A_ID INTEGER REFERENCES AGENT(A_ID);
)

TABLE ESTATE
(
E_ID INTEGER PRIMARY KEY,
E_ADDR VARCHAR(30) NOT NULL,
T_ID INTEGER REFERENCES E_TRANSACTION(T_ID));
)

我正在尝试运行的查询必须回答这个问题:
在2015年1月1日至2015年6月30日期间销售最多房产的代理商

到目前为止,我有这个:

select A_ID, count(A_ID)
from E_TRANSACTION
where t_date >= '01-Jan-2015' and t_date < '30-June-2015'
group by A_ID;

但是它太模糊了,我的导师告诉我只有销售了最多属性的代理的输出,在这种情况下,是E_TRANSACTION表中出现最高的A_ID。换句话说,它应该只输出一个A_ID,它在E_TRANSACTION表中的A_ID堆栈中具有模式号,它基本上显示了该代理所做的事务。

我自己尝试过ORDER BY和GROUP BY,我甚至一起试过它们,但我没有得到任何结果。

我尝试加入两个表E_TRANSACTION和AGENT来获取名称以及修改名称的A_ID,但这也没有用。我假设是因为我输错了代码,或者我犯了非法行为。

到目前为止,我还是无法理解是否使用GROUP BY或ORDER BY,以及我需要的其他任何东西来使这个查询起作用。

其他信息:

  • 使用Oracle 11g Express Edition(sqlplus)
  • 在SQL命令行上运行所有这些
  • 几乎没有使用SQL的经验

一些SQL信息:

插入AGENT
价值观(1111,'Charles Markley','111-PSHMT Way','111-112-1122','cm @sample.example');

插入AGENT
值(1112,'Laurene Lowrey','1010 Learners St','101-121-1211','ll@sample.example');

插入E_TRANSACTION
值(1001,30000.50,'12 -Jan-2015',1111);

插入e_transaction
值(1002,80000.50,'20 -June-2015',1112);

插入ESTATE
值(301,'666 Merry Ln',1001);

插入ESTATE
值(302,'521 Ball Staint Ct',1002);

因此,正如一些人所提到的,我没有为此查询提供足够的详细信息。

最初的尝试是收集每个代理商进行的交易数量,这是通过查找每个代理商的A_ID在E_TRANSACTION表中发生的次数来发现的。

为什么我认为这会起作用?我没有考虑到有多个与TRANSACTION相关的ESTATE。我将不得不在我的要求清单中更改它。我现在设置代码的方式是每个TRANSACTION只有一个ESTATE。所以,这意味着只有一个代理人制作了TRANSACTION,让某人分配了一个房产。因此,每个ESTATE都有一个唯一的唯一TRANSACTION ID以及进行交易的AGENT。允许代理商出售最多5个房产,但这些房产仅被分配一个交易ID。

我提出了几行已在我的数据库中实现的虚拟数据。我无法得到的是完成向我询问的查询所需的正确语法或方法,上面以粗体显示。

如果你不想给我详细说明,那么请至少解决我做错的事情。也许解释为什么我的方法不起作用,以及为什么在这个例子中使用GROUP BY或ORDER BY不起作用。

同样,任何帮助都会很棒。 - 那个随机的家伙

4 个答案:

答案 0 :(得分:0)

在date1和date 2之间销售最多属性的代理

关键词:代理商,已售出,数量(计数),日期

代理意味着您需要:E_Transaction表中的A_ID,代理表中的A_ID和代理表中的A_ID已售出&amp; Count意味着您将需要:来自Transaction表的Count(*)和来自Transaction table

的A_ID

所以最终应该看起来像这样:

选择A_ID , 一个名字 ,计数(T.A_ID) 来自E_Transaction T. 内部联接 A.A_ID上的代理A = T.A_ID 通过...分组     T.A_ID , 一个名字 订购     计数(T.A_ID)

运行此项,根据需要进行调试,因为我手中没有你的数据库,我无法做到。

由于您拥有自己的数据,因此您可以直观地确认它是否落在正确的数量,正确的代理等上。

你们许多人也需要带来房产,因为同一房产可能不止一次出售,这可能会影响到计数,哪些代理人会上升到最高位置。

如果您有具体问题,拼出来,我会回复。请记住,在没有看到您的数据的情况下,我/我们处于不利地位。

答案 1 :(得分:0)

您只查询E_TRANSACTION表,但从表结构来看,似乎一个事务可能涉及多个存档;因此,如果您需要属性数,则必须连接表E_TRANSACTION和ESTATE

select * from (
select * from (
select A_ID, count(E_ID) as num
from E_TRANSACTION,ESTATE
where E_TRANSACTION.t_ID=ESTATE.I_ID 
and t_date   >=to_date('01062014','ddmmyyyy') 
and t_date < to_date('01072014','ddmmyyyy')
group by C_ID) 
order by num desc) 
where rownum<=1

查询更符合您的需求,只有加入两个表才能为您提供全部销售,因此您必须按降序对数据进行排序并获取第一行才能获得最高排名卖家。

这就是我使用两个外部选择的原因: 订购和过滤数据

使用分析函数破坏可以使查询更加紧凑,因为您是初学者,我以教学方式编写。 我更正了你以一种更独立于oracle默认日期/时间设置的格式表达日期的方式,你查询没有考虑30-jun因为&lt;,我考虑了6月的所有日子。

答案 2 :(得分:0)

因此,使用Troy对HAVING子句的建议,你可以这样做:(它在我的一张桌子上工作,但我会用你的)

SELECT ET.A_ID, AG.A_NAME
FROM AGENT AG 
JOIN E_TRANSACTION ET
ON ( ET.A_ID = AG.A_ID )
GROUP BY AG.A_ID, AG.A_NAME
HAVING COUNT(ET.A_ID) =
( SELECT MAX(COUNT(A_ID) FROM E_TRANSACTION
WHERE A_ID IN ( SELECT A_ID FROM AGENT )
GROUP BY A_ID )

这可以为您提供所需的答案 - 因为计数将等于表中的最大计数。使用分析可能有更高级的方法来实现这一点,但我在这些功能方面并不强大。

答案 3 :(得分:0)

这里重要的事情似乎是:

  1. INNER JOIN
  2. COUNT
  3. GROUP BY
  4. ROWNUM
  5. 所以你应该这样做:

    SELECT * FROM (SELECT a.A_ID, a.A_NAME, COUNT(t.A_ID) AS TRANSACTION_COUNT
                    FROM AGENT a
                    INNER JOIN E_TRANSACTION t
                      ON t.A_ID = a.A_ID
                    GROUP BY a.A_ID, a.A_NAME
                    ORDER BY COUNT(t.A_ID) DESC)
      WHERE ROWNUM = 1;
    

    SQLFiddle here

    分享并享受。

    修改

    请注意在a表后使用别名AGENT,在t表后使用E_TRANSACTION。这些表允许通过别名引用这些表中的字段,与键入整个表名相比,这节省了时间和空间。

    没有前置限定符的

    JOININNER JOIN相同。我更喜欢使用INNER JOIN来明白我的意图。

    就时间跨度而言 - 我认为您希望在内部WHERE中添加SELECT子句,以限制在特定时间跨度内获取的行数感兴趣的。

    祝你好运。