sql >> Database >  >> RDS >> Sqlserver

SQL IN-query levert vreemd resultaat op

Dit gedrag, hoewel niet intuïtief, is zeer goed gedefinieerd in de Knowledge Base van Microsoft:

KB #298674:PRB:Subquery lost namen van kolommen op naar buitenste tabellen

Uit dat artikel:

CREATE TABLE X1 (ColA INT, ColB INT)
CREATE TABLE X2 (ColC INT, ColD INT)
SELECT ColA FROM X1 WHERE ColA IN (Select ColB FROM X2)
SELECT ColA FROM X1 WHERE ColA in (Select X2.ColB FROM X2)

Mensen klagen al jaren over dit probleem, maar Microsoft gaat het niet oplossen. Het voldoet tenslotte aan de norm, die in wezen zegt:

Meer informatie vindt u in de volgende Connect "bugs" samen met meerdere officiële bevestigingen dat dit gedrag inherent is aan het ontwerp en niet zal veranderen (dus u zult de uwe moeten veranderen - d.w.z. gebruik altijd aliassen ):

Connect #338468:CTE-kolomnaamomzetting in subquery is niet gevalideerd
Connect #735178:T-SQL-subquery werkt in sommige gevallen niet wanneer IN-operator wordt gebruikt
Connect #302281:niet-bestaande kolom zorgt ervoor dat subquery wordt genegeerd
Connect #772612:Aliasfout wordt niet gerapporteerd binnen een IN-operator
Connect #265772 :Bug met sub selecteer

In uw geval zal deze "fout" waarschijnlijk veel minder snel optreden als u meer betekenisvolle namen gebruikt dan ID, OID en PID. Heeft Order.PID wijs naar Person.id of Person.PID ? Ontwerp uw tabellen zodat mensen de relaties kunnen achterhalen zonder dat ze het u hoeven te vragen. Een PersonID moet altijd een PersonID zijn , ongeacht waar in het schema het is; hetzelfde met een OrderID . Het opslaan van een paar typetekens is geen goede prijs om te betalen voor een volledig dubbelzinnig schema.

Je zou een EXISTS . kunnen schrijven clausule in plaats daarvan:

... FROM dbo.Person AS p WHERE EXISTS 
(
  SELECT 1 FROM dbo.[Order] AS o
  WHERE o.PID = p.id -- or is it PID? See why it pays to be explicit?
);


  1. Het maken van een trigger voor het invoegen van een onderliggende tabel geeft een verwarrende fout

  2. Hoe date_trunc() werkt in PostgreSQL

  3. Een-op-veel-relatie in MySQL - hoe een model te bouwen?

  4. MySql-query:neem dagen op met COUNT(id) ==0, maar alleen in de afgelopen 30 dagen