什么之间的区别INNER JOIN,LEFT JOIN,RIGHT JOIN并FULL JOIN
在MySQL的?
哪个查询更快?
不存在:
SELECT ProductID, ProductName
FROM Northwind..Products p
WHERE NOT EXISTS (
SELECT 1
FROM Northwind..[Order Details] od
WHERE p.ProductId = od.ProductId)
Run Code Online (Sandbox Code Playgroud)
或者不是:
SELECT ProductID, ProductName
FROM Northwind..Products p
WHERE p.ProductID NOT IN (
SELECT ProductID
FROM Northwind..[Order Details])
Run Code Online (Sandbox Code Playgroud)
查询执行计划表明他们都做同样的事情.如果是这种情况,这是推荐的形式?
这基于NorthWind数据库.
[编辑]
刚刚找到这篇有用的文章:http: //weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx
我想我会坚持使用NOT EXISTS.
table1(id,name)
table2(id,name)
查询:
SELECT name
FROM table2
-- that are not in table1 already
Run Code Online (Sandbox Code Playgroud) 我有以下表格:
Users
Banned
SELECT u.*
FROM Users
WHERE u.isActive = 1
AND
u.status <> 'disabled'
Run Code Online (Sandbox Code Playgroud)
我不想包含用户也可能在禁止表中的任何行.
最好的方法是什么?
我可以这样做在子句中放置一个子查询,所以它做了类似的事情:
u.status <> 'disabled' and not exist (SELECT 1 FORM Banned where userId = @userId)
Run Code Online (Sandbox Code Playgroud)
我认为最好的方法是做LEFT JOIN,我怎么能这样做?
使用MySQL 5.x我想有效地从表X中选择所有行,其中表Y中没有相关行满足某些条件,例如
给我X中的所有记录,其中不存在与foo = bar相关的Y.
SELECT count(id) FROM X
LEFT OUTER JOIN Y ON y.X_id = X.id AND y.foo = 'bar'
WHERE y....?
Run Code Online (Sandbox Code Playgroud)
据我所知,左外连接保证为左(第一)表中的每一行产生一行 - 在这种情况下为X - 是否找到了连接表中令人满意的行.我想要做的只是选择那些没有找到行的行.
在我看来,如果没有匹配的记录,y.X_id应为NULL,但此测试似乎不起作用.y.X_id = 0或!y.X_id也不是.
编辑:纠正的转录错误(ON不是AS),这是由几个回答指出的.修正了语法错误.
我想运行一个mysql查询来从表films中选择所有行,其中title列的值不存在于另一列(collection)的所有值中的任何位置.
这是我的表的简化版本,内容如下:
mysql> select * from films;
+----+--------------+--------------+
| id | title | collection |
+----+--------------+--------------+
| 1 | Collection 1 | NULL |
| 2 | Film 1 | NULL |
| 3 | Film 2 | Collection 1 |
+----+--------------+--------------+
Run Code Online (Sandbox Code Playgroud)
这是我的查询:
mysql> SELECT * FROM films WHERE title NOT IN (SELECT collection FROM films);
Empty set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我希望选择与标题行Film 1和Film 2,但我的查询返回任何行.
这是表结构:
CREATE TABLE `films` (
`id` int(11) …Run Code Online (Sandbox Code Playgroud) 我试图找到一个优雅的解决方案,以SQL查询的形式解决以下问题.
新记录将插入Log表中.我需要检测我之前没见过的任何新记录(插入在最后一小时内)并生成警报(例如,这些记录的数量> 0)
ID, Url, DOB
1, site1.com/page1, "5/06/2012 20:01"
2, site2.com/page2, "5/06/2012 21:20"
3, site1.com/page1, "6/06/2012 10:05"
Run Code Online (Sandbox Code Playgroud)
如果"now"是6/06/2012 10:40 - 我看到插入了1条新记录(id = 3),但我不想生成警报,因为我们之前已经看过这个URL(id = 1) .
如果我们有4,site3.com/pageX,"6/06/2012 10:08"那么我想生成一个警报(返回计数= 1),因为这一行是在最后一小时插入的,我们还没有看到它之前.
实施它的最佳方法是什么?理想情况下没有嵌套查询
我想在另一个表示例中删除所有没有现有外键的行:
table1
+----+-------+
|id | data |
+----+-------+
| 1 | hi |
+----+-------+
| 2 | hi |
+----+-------+
| 3 | hi |
+----+-------+
| 4 | hi |
+----+-------+
| 5 | hi |
+----+-------+
table2
+----+-------+
|a_id| data |
+----+-------+
| 1 | hi |
+----+-------+
| 20 | hi |
+----+-------+
| 3 | hi |
+----+-------+
| 40 | hi |
+----+-------+
| 5 | hi |
+----+-------+
Run Code Online (Sandbox Code Playgroud)
该查询将删除table2上ID为#20和40的行.
我需要这样做,以便我可以建立与table1和table2的关系.
我正在优化一些SQL查询(这可以被认为是我最近发布的问题的第2部分)并用NOT EXISTS谓词替换了一些NOT IN
我是否正确地认为这样做的主要好处是,使用NOT EXISTS可以获得声明在找到单个匹配时终止的好处,但是对于计数子查询而言,NOT IN将需要进行全表扫描?
如果选择的数据包含NULL,NOT IN似乎还需要额外的工作,这是正确的吗?
在我在proc中实现它们之前,我需要确保第二个语句比这两个案例中的第一个语句(和功能上等效的)更好:
情况1:
--exclude sessions that were tracked as part of a conversion during the last response_time minutes
-- AND session_id NOT IN (SELECT DISTINCT tracked_session_id
-- FROM data.conversions WITH (NOLOCK)
-- WHERE client_id = @client_id
-- AND utc_date_completed >= DATEADD(minute, (-2) * cy.response_time, @date)
-- AND utc_date_completed <= @date
-- AND utc_date_clicked <= @date)
AND NOT EXISTS (SELECT 1
FROM data.conversions WITH (NOLOCK)
WHERE client_id = @client_id
AND utc_date_completed >= DATEADD(minute, (-2) …Run Code Online (Sandbox Code Playgroud) 在我的rails应用程序中,我有两个表 - device_ports和circuits.我的目标是获得一个列表device_ports,其id未在使用physical_port_id的列circuits表.
我之前在其他表上做过类似的事情但是这里我的查询只返回一行,当它应该返回23行时 - 这个设备有24个设备端口,一个正在使用中.
select id, name, device_id, multiuse
from device_ports
where (device_id = 6 and multiuse = 1)
or device_ports.id not in (select physical_port_id from circuits)
Run Code Online (Sandbox Code Playgroud)
因此,此查询获取所有多用途端口(因此,即使在外键中引用了id,仍应返回此行),并且还应获取device_id为6但在电路中未引用的所有行,但只有多用途行是被退回.
查询的结果是
id | name | device_id | multiuse
------------------------------------
268 | test-1 | 6 | 1
Run Code Online (Sandbox Code Playgroud)
我确实尝试创建一个sql小提琴,但构建似乎暂停.
CREATE TABLE `device_ports` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`device_id` int(11) DEFAULT NULL,
`name` tinytext,
`speed` tinytext,
`multiuse` tinyint(1) DEFAULT NULL,
`created_at` …Run Code Online (Sandbox Code Playgroud) 假设我有两个表(tb1,tb2),它们都具有以下模式:
CREATE TABLE tb1 (
col1 INT NOT NULL,
col2 TEXT NOT NULL,
col3 TEXT NOT NULL,
col4 REAL
);
Run Code Online (Sandbox Code Playgroud)
如何查找记录tb1中不存在的tb2列上col1,col2,col3?
我研究了这个,这个和这个但到目前为止他们都只在一个专栏上找到了记录.我也在这些链接中使用了代码/逻辑,但最终以非常差的性能返回错误的结果(tb1上的45K记录,tb2上的1.7M记录).我正在尝试在SQLite上实现它.
如果你想看,这是我的示例代码(使用左连接w/where为null),但不要依赖它:
SELECT *
FROM tb1
LEFT JOIN tb2
ON
tb1.col1 = tb2.col1 AND
tb1.col2 = tb2.col2 AND
tb1.col3 = tb2.col3
WHERE
tb2.col1 IS NULL AND
tb2.col2 IS NULL AND
tb2.col3 IS NULL
Run Code Online (Sandbox Code Playgroud) select
film.title
from film
left outer join filmitem ON film.filmid = filmitem.filmid
left outer join filmgenre ON filmitem.filmid = filmgenre.filmid
where
film.title = title and filmgenre.genre NOT IN (
select genre from genre
where genre != 'Comedy' and genre != 'Horror')
group by title;
Run Code Online (Sandbox Code Playgroud)
我想找到只包含"Comedy"和"Horror"类型的电影.当我运行这个查询时,我会看到喜剧和其他性别的电影,但我想排除其他性别,只得到只有喜剧和恐怖的电影.有什么建议吗?
sql ×12
mysql ×5
sql-server ×5
join ×2
outer-join ×2
inner-join ×1
notin ×1
optimization ×1
plsql ×1
postgresql ×1
sqlite ×1
t-sql ×1