2012-04-05 13 views
-1

Ich habe eine Tabelle mit 3 Spalten. Hier ist ein Beispiel mit nur wenigen Einträgen zur Demo. Die Tabelle gibt die Daten an, um die sich der Preis eines Artikels ändert. Ich brauche eine Abfrage, die mir die Preise für alle Artikel an einem bestimmten Datum sagt. Das spezifische Datum kann zwischen Preisänderungen liegen. Die Preisänderungen um Mitternacht, so dass der Zeitpunkt der Änderung ist, dass der Preis von da an bis und am Tag vor der vorherige Änderung:Grundlegende SQL-Abfrage Hilfe benötigt

itemCode datePriceEffective price 
AB   2012-01-01   9.99 
AB   2012-03-02   10.50 
XY   2011-09-20   34.99 

Ich wünsche alle Einzelteile erhalten Preise für ein bestimmtes Datum. Es gibt keinen Eintrag für jedes Datum, nur die Daten, an denen sich der Preis ändert. so 2012-03-05 zurückkehren würde

AB 10.50 
XY 34.99 

und 2012-02-27 zurückkehren würde:

AB 9.99 
XY 34.99 

Die SQL-Abfrage benötigt diese entgeht mir zu bekommen. Antworten geschätzt.

Bearbeitet, da die Antworten in die falsche Richtung gehen, siehe Kursivschrift zum Bearbeiten.

+0

haben Sie eine weitere Spalte mit Daten? Weil die Daten, die Sie in der Abfrage angeben, in keiner Spalte zu sehen sind. – Virus

Antwort

1

Sie müssen auf den Tisch kommen zurück, wie folgt:

declare @effdate datetime 
set @effdate = CONVERT(datetime,'2012-02-27') 

;WITH CTE_DATA as (
    select itemCode='AB', datePriceEffective = CONVERT(Datetime,'2012-01-01'), price = 9.99 
    union all select itemCode='AB', datePriceEffective = CONVERT(Datetime,'2012-03-02'), price = 10.50 
    union all select itemCode='XY', datePriceEffective = CONVERT(Datetime,'2011-09-20'), price = 34.99 
) 
select 
    d.itemcode, 
    price 
from 
    CTE_DATA d 
    join (
     select 
      itemcode, 
      effdate = MAX(datepriceeffective) 
     from CTE_DATA sub where sub.datepriceeffective <= @effdate 
     group by itemcode 
    ) x 
     on x.itemCode = d.itemCode 
     and x.effdate = d.datePriceEffective 

Beachten Sie, dass der WAK nur für dieses Beispiel ist, sollten Sie es für Ihre realen Tisch tauschen.

UPDATE: Ein alternativer Ansatz ist ROW_NUMBER und PARTITION wie folgt zu verwenden:

SELECT   
    itemcode, 
    price 
FROM  
    (
     SELECT 
      itemcode, 
      price, 
      rowno = ROW_NUMBER() over (partition by itemcode order by datePriceEffective desc) 
     from 
      CTE_DATA 
      where datePriceEffective <= @effdate 
    ) x 
where 
    rowno = 1 

(ersetze diese select für die in der vorherigen Abfrage auf die Daten versuchen)

+0

das sieht unnötig kompliziert aus. –

+0

Der CTE dient nur dazu, einige Daten zu generieren, auf denen er ausgeführt werden kann. Die tatsächlichen Abfragen sind einfach genug. Nikolas Lösung ist ähnlich wie meine zweite Antwort, filtert aber die benötigten Ergebnisse besser. –

+1

als akzeptierte Antwort markiert, da dies der erste war, in dem gearbeitet wurde. Einige andere arbeiten auch –

2
SELECT itemCode,price FRom TableNameHere WHERE datePriceEffective <= '2012-03-05' 

Bearbeiten nach mehr Informationen - eine ‚einfache‘ Antwort auf hoffentlich machen es einfach zu folgen.

Sie bekommen neusten Ergebnisse Termin für das Element, das in Ihren gewünschten Datumsbereich gültig ist, und dann die Tabelle Verbindung zu sich selbst, den Preis zu diesem Zeitpunkt der Annahme

SELECT t1.itemCode,t1.price FROM 
    (
    SELECT itemCode,MAX(datePriceEffective) AS datePriceEffective 
    FROM TableNameHere 
    WHERE datePriceEffective <= '2012-03-05' 
) a 
INNER JOIN TableNameHere t1 ON t1.itemCode = a.itemCode AND t1.datePriceEffective = a.datePriceEffective 
+0

Das kann nicht stimmen Es gibt keine Einträge für dieses Datum! –

+0

Entschuldigung, ja Sie haben dieses Datum in Ihrer Frage aufgelistet und dann Ihre Frage bearbeitet, um zu erklären, was Sie wollen ... –

+0

Vorausgesetzt, datePriceEffective ist eine Datetime-Spalte, können Sie weniger als und größer als Operatoren verwenden. –

0

zu bekommen, dass Sie eine weitere Spalte namens ' GivenDate ', unten ist die Abfrage.

SELECT itemCode, price 
FROM tblName 
WHERE GivenDate= '2012-03-05' 
+0

Ich habe keine andere Spalte –

+0

müssen Sie datePriceEffective Spalte verwenden, um die Ergebnisse für das angegebene Datum zu erhalten? Und der datePriceEffective wird häufig aktualisiert? – Virus

+0

Wenn dies der Fall ist, können Sie die Daten in der Spalte datePriceEffective abfragen. Sie können kein 'Anderes' gegebenes Datum verwenden. – Virus

1
declare @date datetime = '2012-03-05' 

select distinct itemcode, 
    (
     select top(1) itemprice 
     from mytable mt2 
     where 
      mt1.itemcode = mt2.itemcode and 
      mt2.datepriceeffective <= @date 
     order by datepriceeffective desc 
    ) as itemprice 
from 
    mytable mt1 
where 
    datepriceeffective <= @date 
+0

das funktioniert dank. Obwohl nicht der erste, so verpasst auf die Annahme. –

3

Dies ruft den ersten Datensatz in absteigender Reihenfolge von datePriceEffective pro itemCode ab.

select top 1 with ties * 
from ATable 
where datePriceEffective <= @givenDate 
order by row_number() over (partition by itemCode 
          order by datePriceEffective desc) 
+0

+1: Das ist eine große Verwendung von 'WITH TIES' - gibt eine wirklich saubere Lösung !. –

+0

das funktioniert dank. Obwohl nicht der erste, so verpasst auf die Annahme. –

1
SELECT b.itemCode, 
(SELECT Price FROM dbo.tblProducts a WHERE datePriceEffective = 
(SELECT MAX(a.datePriceEffective) FROM dbo.tblProducts a WHERE a.itemCode = b.itemCode)) AS Price 
FROM dbo.tblProducts b 
WHERE b.datePriceEffective <= '2012-03-05' 
GROUP BY b.itemCode 

Ich habe es getestet! Es wird Ihnen die aktuellsten Preis für jeden Artikel

0

Dies funktioniert auf SQL2000

SELECT  s.itemCode 
      , (SELECT  TOP 1 price 
       FROM  #MyTable 
       WHERE  itemCode = s.itemCode 
          AND datePriceEffective < @SearchDate) AS price 
FROM  (
      SELECT DISTINCT itemCode 
      FROM #MyTable 
      ) s