标签: subquery

使用 WHERE NOT IN 子选择子句提高性能

在以下查询中,我必须为每个客户计算交易。但是,我必须从结果集中完全排除交易时间超过一年的客户。

查询优化器不应该足够聪明,只为每个客户评估一次存在吗?

--Count transactions on customers that are less than 1 year old

SELECT t1.CUSTID, COUNT(*)
FROM CUST_TRX t1
WHERE NOT EXISTS ( 
  SELECT FIRST 1 1 
  FROM CUST_TRX t2 
  WHERE 
    t2.CUSTID = t1.CUSTID AND
    t2.DATED < CURRENT_DATE - 365
  GROUP BY t2.CUSTID
)
GROUP BY t1.CUSTID
Run Code Online (Sandbox Code Playgroud)

我的查询计划中没有自然。此查询的执行就像数据库为每个事务运行存在子句,而不是为每个客户运行它。如果我删除GROUP BY子查询中的,则性能相同。

有没有更好的方法来做到这一点,以便我可以从数据库中获得更好的性能?SELECT如果可能的话,希望一个简单的查询能够避免 CTE(这会带来其他挑战)。

由于其他GROUP BY条件(此处未显示),我无法简单地检查MIN(DATED),我确实需要执行另一个查询。

performance execution-plan subquery firebird query-performance

4
推荐指数
1
解决办法
7679
查看次数

编写查询以查找所有高于其经理的员工工资

我有两个带有一些虚拟数据的表。我需要找到所有比他们的经理赚更多的员工。我相信这个练习的重点是学习如何做子查询。

我可以隔离经理、他们的薪水和他们工作的公司,但我不知道如何继续将他们的员工薪水与 SQL 中的经理进行比较。回到我身边的错误是“当子查询没有通过 EXISTS 引入时,只能在选择列表中指定一个表达式。” 我明白,但如果我不能从子查询中至少传递经理的姓名和薪水,那么我不知道如何解决问题。

如果有人可以指出我已回答的类似帖子或一些可以提供一些见解的阅读,我将不胜感激。

我的查询获取有关经理的信息

SELECT DISTINCT w.salary, w.pname, w.cname
FROM WorksFor w
INNER JOIN Manages m
ON w.pname = m.mname
Run Code Online (Sandbox Code Playgroud)

员工/公司表

CREATE TABLE WorksFor (
employerID int identity(1,1) primary key,
pname varchar(30),
cname varchar(20),
salary int
);

INSERT INTO WorksFor(pname,cname,salary)
VALUES
('John Smith','BigStore',27500),
('Jane Doe','SmallStore',19000),
('Adam Scott','BigStore',50000),
('Bonnie Noel','SmallMfg',25000),
('Cassie Johnson','BigStore',35000),
('Donald Eckerson','SmallStore',29000),
('Erin Joel','SmallMfg',49000);

CREATE TABLE Manages (
manageID int identity(1,1) primary key,
pname varchar(30),
mname varchar(30)
);
Run Code Online (Sandbox Code Playgroud)

经理表

INSERT INTO Manages(pname,mname)
VALUES
('John …
Run Code Online (Sandbox Code Playgroud)

sql-server subquery

4
推荐指数
1
解决办法
3万
查看次数

PostgreSQL 中的子查询魔法

我有一个疑问:

update product_product 
set (write_date, default_code) = (LOCALTIMESTAMP, 'update') 
where product_tmpl_id in (
    select distinct product_tmpl_id 
    from product_template 
    where type='import');
Run Code Online (Sandbox Code Playgroud)

而且需要7个小时才能完成。但是,当我执行子查询时:

select distinct product_tmpl_id 
from product_template 
where type='import';
Run Code Online (Sandbox Code Playgroud)

我收到错误:

列“product_tmpl_id”不存在

product_tmpl_id表中没有列product_template

这是我的错误。第一个查询应该是:

update product_product set (write_date,default_code) = (LOCALTIMESTAMP,'update') 
where product_tmpl_id in
 (select distinct id from product_template where type='import');
Run Code Online (Sandbox Code Playgroud)

它只需要几秒钟即可运行。

所以我的问题如下:

  • 为什么第一个查询没有失败?
  • 为什么要运行这么长时间?
  • 它到底做了什么?

结果select version();

PostgreSQL 9.4.3 on x86_64-unknown-linux-gnu, 
compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
Run Code Online (Sandbox Code Playgroud)

postgresql subquery postgresql-9.4

4
推荐指数
1
解决办法
480
查看次数

从 MySQL 子查询返回 2 列?

我是 MySQL 编程新手,但有一个问题。我创建了这个查询:

SELECT *,
       topics.createdate AS TopicCreateDate,
       (SELECT (SELECT username
                FROM   users
                WHERE  id = topicanswers.userid)
        FROM   topicanswers
        WHERE  topicid = topics.id
        ORDER  BY id DESC
        LIMIT  1)        AS LastPost
FROM   topics
       INNER JOIN categories
               ON topics.categoryid = categories.id
       INNER JOIN users
               ON topics.userid = users.id
ORDER  BY topics.lastupdate DESC
Run Code Online (Sandbox Code Playgroud)

此查询列出所有Topics、联接类别和用户,UserID以及类别 IDTopicsUsername来自TopicAnswersas LastPost。它命令它们LastUpdateTopics由 控制的范围内下降TRIGER

它工作得很好,但是这个子查询有一个问题:

            (SELECT (SELECT username
                    FROM   users
                    WHERE  id …
Run Code Online (Sandbox Code Playgroud)

mysql join subquery

4
推荐指数
1
解决办法
4353
查看次数

我怎样才能返回每个团队的最大总和?

我有很多团队,我想知道每个团队的总和的最大值。

这是我的查询:

SELECT campaign_id, 
       campaign_identifier, 
       team, 
       campaign_name, 
       Month(time) AS month, 
       Sum (total) AS Total 
FROM   campaign 
WHERE  Year(time) = Year(Now()) 
       AND Month(time) = 12 
GROUP  BY campaign_identi, 
          team 
Run Code Online (Sandbox Code Playgroud)

谢谢。

mysql subquery

4
推荐指数
1
解决办法
1771
查看次数

SQL Server 2014 中的相关子查询

我正在运行一个相关的子查询来找出不同城市、州的供应商列表(按供应商名称),即我们想知道与其他供应商没有共同城市和州的供应商。似乎可以自行加入。

如果可能,请仅提供提示。

供应商表是:

Vendors(VendorID P, VendorCity, VendorState, VendorName,...)
Run Code Online (Sandbox Code Playgroud)

这就是我所拥有的:

Select VendorName, VendorCity, VendorState from Vendors AS V1 where
         VendorCity, VendorState NOT IN (Select VendorCity, VendorState FROM
          Vendors AS V2 where V2.VendorID <> V1.VendorID)
Run Code Online (Sandbox Code Playgroud)

这是我收到的错误消息:

消息 4145,级别 15,状态 1,第 2 行 在“,”附近的预期条件的上下文中指定的非布尔类型的表达式。

我不明白为什么要引用布尔类型,因为这不是 EXISTS 或其他相关查询。

sql-server subquery

4
推荐指数
2
解决办法
389
查看次数

外部自联接过滤器与子查询

我有一张表存储有关门票的信息。售票时有一个记录,使用票时有另一个记录。有一个名为 TransType 的列,它被设置为“已售出”或“已使用”以标记它是哪一个。表中还有其他列,其中一些列在销售时包含值,但在使用时不包含值,反之亦然。该表实际上是数据仓库风格的事实表。

在其他事情中,我正在计算销售和使用之间的时间差,因此我将表格加入到自己的表格中,以便为每张票获取一条记录,以便能够在同一记录中计算两个事件的时间戳。

我需要包括所有售出的门票,所以外连接应该可以解决这个问题。

首先我运行了这个查询

select x.* 
from factI as x
left join factI as y on x.tickedId = y.tickedId
where x.TransType = 'sold'
and y.TransType = 'used'
Run Code Online (Sandbox Code Playgroud)

当我运行它时,过滤器 x.TransType = 'sold' 不起作用,并且查询实际上返回所有记录的结果,无论 TransType 是什么。如果我使用内连接,这会起作用,但显然不会返回尚未使用的票证。

所以我将查询更改为这个给我正确结果的查询。

select * from (
   select * from factI where TransType = 'sold'
) as x
left join (
   select * from factI where TransType = 'used'
) as y on x.ticketId = y.ticketId
Run Code Online (Sandbox Code Playgroud)

当我使用外部(左)连接时,为什么第一个查询中的 where 子句没有正确过滤掉?

join sql-server subquery sql-server-2012

4
推荐指数
1
解决办法
2139
查看次数

通过 Seatrow 选择连续座位

SELECT TOP N seats.*, eventtickets.eticketprice from seats 
INNER JOIN eventtickets ON eventtickets.etickettype = seats.seattype 
WHERE ((Seats.seatType ='BOXSEAT') 
AND seatID not in (select seatID from ticketsales WHERE eventID=6))
ORDER BY convert (int, seats.seatSection), seats.seatrow ASC
Run Code Online (Sandbox Code Playgroud)

我上面的查询生成了 N 个座位中的最佳可用数量,但它会填满一个部分,然后将该订单的其余部分放在下一个部分。我需要它来找到一个新的部分,所有 N 个座位都可用。如果座位在TicketSales桌子上,则不可用。如果salecategory为 Null,则表示票证尚未售出/阻止/保留,因此可用。

它显然限制在 6 个座位上,但我确实有一个部分,一排有 30 多个座位。

Section 1: 
Row 1: 1-2-3
Row 2: 4-5-6

Section 2:
Row 1: 1-2-3
Row 2: 4-5-6
Run Code Online (Sandbox Code Playgroud)

等等。

我没办法。连续盯着这个看了两天,我的脑子里一片空白。我在 SQL 方面非常薄弱,令人惊讶的是我远远超过了这一点。我想我已经接近了,但没有辣酱玉米饼馅。

请参阅随附的 2 个主表的图片。我只需要seatpricefromeventtickets表所以它不是那么重要。

我感谢你在这方面给我的任何帮助。

售票处

座位

sql-server subquery

4
推荐指数
1
解决办法
710
查看次数

MySQL 重用 select 别名

我目前有一个查询,我正在执行两个子查询来获取 X、Y 数据:

SELECT
  t.series AS week,
  ( ... ) X,
  ( ..., AND ... ) Y,
  ROUND(( ... ) * 100) / ( ..., AND ... ), 2) Z
FROM series_tmp t
Run Code Online (Sandbox Code Playgroud)

Y 是 X 的子集,因为我只对现有条件应用一个附加条件,如果 X 是:

SELECT COUNT(*)
FROM t1
INNER JOIN t2
ON t2.id = t1.another_id
WHERE t2.something = 1
AND t1.date BETWEEN t.series AND t.series + INTERVAL 6 DAY
Run Code Online (Sandbox Code Playgroud)

那么 Y 还有一个附加的 AND 条件:

SELECT COUNT(*)
FROM t1
INNER JOIN t2
ON t2.id = t1.another_id …
Run Code Online (Sandbox Code Playgroud)

mysql subquery alias

4
推荐指数
1
解决办法
5176
查看次数

更新期间意外违反唯一约束

foo在具有两列(id和)的表中seq,我想为seq具有任意 . 的所有记录添加+1 seq > 4738。计划是在seq=4739所有seq > 4738记录移动+1 后立即插入一条新记录。

这是桌子。

CREATE TABLE foo
(
  id uuid NOT NULL,
  seq integer NOT NULL,
  CONSTRAINT seq_key UNIQUE (seq)
)

CREATE UNIQUE INDEX idx_id
  ON foo
  USING btree
  (id);

CREATE UNIQUE INDEX idx_seq
  ON foo
  USING btree
  (seq);
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下查询实现 +1 转变。请注意,我使用子查询尝试> 4738按降序更新记录(即假设 max seq=10000,则首先更新最后一条记录(10000->10001),然后更新倒数第二条记录(seq=10000此时不存在,seq=9999-> seq=10000(没有违反约束),然后是 9998 -> 9999,...以避免在任何时候发生唯一的约束违反。但是,这假设更新查询是顺序执行的,而这似乎并不是发生的情况。

跑步时

UPDATE foo SET seq=anon_1.new_seq FROM …
Run Code Online (Sandbox Code Playgroud)

postgresql subquery update unique-constraint

4
推荐指数
1
解决办法
4861
查看次数