我有下表,
-- Generated with pg_dump, some constraints are missing
CREATE TABLE articulos_factura_venta (
fila integer NOT NULL,
cantidad integer NOT NULL,
color integer NOT NULL,
talla integer NOT NULL,
estado integer DEFAULT 2 NOT NULL,
origen integer,
factura integer NOT NULL,
articulo integer NOT NULL,
precio integer NOT NULL,
vendedor integer,
anulado boolean DEFAULT false,
iva double precision DEFAULT 12.0,
fecha date DEFAULT ('now'::text)::date NOT NULL
);
它包含以下行 1
fila | cantidad | color | talla | estado | origen | factura | articulo | precio | vendedor | anulado | iva | fecha
------+----------+-------+-------+--------+--------+---------+----------+--------+----------+---------+-----+------------
0 | 1 | 0 | 3 | 6 | 18 | 28239 | 1325 | 455 | 6 | f | 0 | 2015-04-22
1 | 1 | 0 | 2 | 6 | 93 | 28239 | 2071 | 615 | 6 | f | 0 | 2015-04-22
2 | 1 | 0 | 49 | 6 | 76 | 28239 | 2013 | 545 | 6 | f | 0 | 2015-04-22
3 | 1 | 0 | 78 | 6 | 85 | 28239 | 2042 | 235 | 6 | f | 0 | 2015-04-22
4 | 1 | 0 | 49 | 6 | 81 | 28239 | 2026 | 615 | 6 | f | 0 | 2015-04-22
5 | 1 | 0 | 50 | 6 | 90 | 28239 | 2051 | 755 | 6 | f | 0 | 2015-04-22
6 | 1 | 0 | 1 | 38 | 21 | 28239 | 1780 | 495 | 6 | f | 0 | 2015-04-22
7 | 1 | 15 | 2 | 38 | 16 | 28239 | 1323 | 845 | 6 | f | 0 | 2015-04-22
8 | 1 | 0 | 4 | 38 | 18 | 28239 | 1326 | 455 | 6 | f | 0 | 2015-04-22
2 | 1 | 0 | 49 | 22 | 76 | 28239 | 2013 | 545 | 6 | f | 0 | 2015-04-22
问题非常简单,为什么这个查询不输出任何行?
SELECT
filas.factura,
filas.fila,
filas.cantidad,
retirados.cantidad,
vendidos.cantidad,
filas.estado
FROM
articulos_factura_venta AS filas
LEFT JOIN
articulos_factura_venta AS retirados
USING (fila, color, talla, origen, factura, articulo, vendedor)
LEFT JOIN
articulos_factura_venta AS vendidos
USING (fila, color, talla, origen, factura, articulo, vendedor)
JOIN
articulos
ON articulos.codigo = filas.articulo
JOIN
tallas
ON tallas.codigo = filas.talla
JOIN
colores
ON colores.codigo = filas.color
JOIN
empleados
ON empleados.codigo = filas.vendedor
WHERE
filas.factura = 28239 AND
retirados.estado & 16 <> 0 AND
vendidos.estado & 8 <> 0 AND
filas.estado & 4 <> 0
ORDER BY
filas.estado
我希望此查询从cantidad
fila == 2
的{{1}}行中减去estado & 16 <> 0
,因此我预计只有一行fila == 2
和{{1} }
注意:位标志不是硬编码的,它们是我在用c ++编写的实际应用程序中使用的cantidad = 0
。
enum
[1] 该表包含数千行,但我只对这些行感兴趣,即database# \d articulos_factura_venta
Column | Type | Modifiers
----------+------------------+--------------------------------------
fila | integer | not null
cantidad | integer | not null
color | integer | not null
talla | integer | not null
estado | integer | not null default 2
origen | integer |
factura | integer | not null
articulo | integer | not null
precio | integer | not null
vendedor | integer |
anulado | boolean | default false
iva | double precision | default 12.0
fecha | date | not null default ('now'::text)::date
Indexes:
"articulos_factura_venta_pkey" PRIMARY KEY, btree (fila, factura, articulo, precio, talla, color, estado)
"buscar_cantidad_venta_idx" btree (articulo, talla, color, origen)
Foreign-key constraints:
"cantidades_venta_articulo_fkey" FOREIGN KEY (articulo) REFERENCES articulos(codigo)
"cantidades_venta_color_fkey" FOREIGN KEY (color) REFERENCES colores(codigo) ON UPDATE CASCADE ON DELETE RESTRICT
"cantidades_venta_factura_fkey" FOREIGN KEY (factura) REFERENCES ventas(codigo)
"cantidades_venta_origen_fkey" FOREIGN KEY (origen) REFERENCES compras(codigo) ON UPDATE CASCADE ON DELETE RESTRICT
"cantidades_venta_talla_fkey" FOREIGN KEY (talla) REFERENCES tallas(codigo) ON UPDATE CASCADE ON DELETE RESTRICT
"cantidades_venta_vendedor_fkey" FOREIGN KEY (vendedor) REFERENCES empleados(codigo)
的行。
答案 0 :(得分:2)
长话短说,它可能会像这样:
WHERE
特别是这些添加的LEFT JOIN
条款使您尝试JOIN
的相应表格无效,并使其表现得像AND r.estado & 16 <> 0
AND v.estado & 8 <> 0
:
JOIN empleados e ON e.codigo = f.vendedor
另一个棘手的细节:
f.vendedor
但NULL
可以是f.vendedor IS NULL
。您打算从结果中删除articulos
的所有行吗?因为这就是联接的作用。
我评论了tallas
,colores
和NOT NULL
的三个联接。 FK列为serial
,连接只会花费成本时间而您不使用任何列。
超过7列的主键约束是糟糕的主意。昂贵而笨重。添加代理主键 - 我建议使用UNIQUE
列:
您仍然可以使用CREATE TABLE articulos_factura_venta (
afv_id serial PRIMARY KEY -- pick your column name
fila integer NOT NULL,
cantidad integer NOT NULL,
color integer NOT NULL,
talla integer NOT NULL,
estado integer DEFAULT 2 NOT NULL,
factura integer NOT NULL,
articulo integer NOT NULL,
precio integer NOT NULL,
fecha date NOT NULL DEFAULT now()::date,
origen integer,
vendedor integer,
anulado boolean DEFAULT false, -- NOT NULL ?
iva double precision DEFAULT 12.0,
CONSTRAINT uni7 -- pick your contraint name
UNIQUE (fila, factura, articulo, precio, talla, color, estado)
);
约束强制实现7列的唯一性 - 如果您实际需要它。
关于UNIQUE
和PRIMARY KEY
约束(评论中的每个请求):
建议的表格设计:
...
LEFT JOIN articulos_factura_venta r ON r.afv_id = f.afv_id
AND r.estado & 16 <> 0
LEFT JOIN articulos_factura_venta v ON v.afv_id = f.afv_id
AND v.estado & 8 <> 0
...
然后可以将查询简化为:
{{1}}
答案 1 :(得分:1)
这是一个被称为链式外连接的问题。首先执行LEFT OUTER JOIN
NULL
之后,它会为右表中与左表不匹配的列创建NULL
值。然后,当您将INNER JOIN
值加上LEFT JOIN
之后,这些行就会消失,就像您从未在第一时间进行外部联接一样。
有两种解决方案:
JOIN
,所有后续LEFT
必须为FULL
或INNER JOIN
RIGHT JOIN
并执行表格
想成为OUTER JOIN
此外,当您LEFT
或RIGHT
WHERE
时,将ON
CLAUSE条件移至{{1}通常是个好主意而不是WHERE
子句。这是一个非常棘手的问题,但要查看FILTER条件和JOIN
条件之间的区别,以及它们何时应放在WHERE
vs ON
子句中。