Avatar billede Slettet bruger
04. december 2013 - 13:53 Der er 11 kommentarer og
1 løsning

Bruge variable i case

Hej
Jeg er helt ny i brugen af SQL.

Jeg har fået noget til at virke, men nu har jeg ramt muren.

Nedenstående virker som en del af noget mere. Jeg vil nu gerne have LA i en variable, som jeg kan bruge senere i min SQL-kode.

Jeg har forsøgt mig med
Declare @LA og så gøre følgende:
@LA = ,(CASE WHEN LA IS NULL THEN... osv.

Er den en som kan forklare mig mig hvorfor det fejler?

SELECT
              [OrderID]
              ,[CustomerID]
              ,[CustomerName]
              ,[CustomerCountry]
              ,[OfficeID]
              ,[OfficeName]
              ,[PartnerID]
              ,[PartnerName]
              ,[OrderID]
              ,[Expiration]
              ,[LicenseID]
              ,SUM([RetailTotal]) as RetailTotal
              ,SUM([PartnerTotal]) as PartnerTotal
              ,SUM([OfficeTotal]) as Officetotal
              ,[InvoiceDate]
              ,(CASE WHEN LA IS NULL THEN
                    (CASE
                          WHEN [OrderLineType] = 'product' THEN '1010'
                            WHEN [OrderLineType] = 'maintenance' AND [Expiration] > [InvoiceDate] + 540 THEN 'LTM1020'
                          WHEN [OrderLineType] = 'upgrade' AND [Expiration] IS NOT NULL THEN '1020'
                          WHEN [OrderLineType] = 'upgrade' THEN '1010'
                          WHEN [OrderLineType] = 'maintenance' THEN '1020'
                          ELSE [OrderLineType]
                    END)
              ELSE
                    LA
              END
              ) as LA
Avatar billede Syska Mester
04. december 2013 - 15:07 #1
Hvad er fejlen?
Avatar billede Syska Mester
04. december 2013 - 15:08 #2
Problemet er måske også lidt at din SELECT kan returnere flere rækker og hvad er @LA så sat til?

Du bør holde business logic ude af din SQL for din egen og adnres skyld.
Avatar billede Slettet bruger
04. december 2013 - 17:06 #3
Fejlen henviser til det der "as LA" (tror jeg).

Jeg forstår ikke hvad det vil sige at holde business logic ude ar min SQL.

Jeg henter data ind i et Excel ark, og der skal jeg bruge en kolonne som har samme værdi som LA, bortset fra når LA = 1020 og en værdi senere er 1, så skal LA være 1010. Derfor prøver jeg at stoppe LA i en variable, som jeg så kan bruge lidt senere.

Giver det mening?
Avatar billede Syska Mester
04. december 2013 - 17:17 #4
Business logic er hvis du programmere i f.eks .NET, så placere man logik der i stedet for i SQL ... men hvis du trækker det direkte ind i Excel så må du godt. Så bare glem min sætning.

Problemet med at smide data i en variable er at den kun indeholder en værdi og din query har mange værdier.

Du må få en mere præcis fejl end det. Hvor skriver den at det ikke virker? Hvordan ved du det ikke virker? Er der flere informationer du måske tror jeg kunne få brug for at løse dit problem, så skriv dem endelig. Hellere for mange informationer end for lidt.

Men hvad TABLE selecter du fra? Det lader ikke til at din SQL query er komplet.

Jeg vil i hvert fald ikke antage du skal bruge en variable.
Avatar billede Slettet bruger
04. december 2013 - 19:33 #5
Hej igen

Jeg får følgende fejl

Msg 156, Level 15, State 1, Line 33
Incorrect syntax near the keyword 'as'.
Msg 102, Level 15, State 1, Line 38
Incorrect syntax near '>'.
Msg 102, Level 15, State 1, Line 47
Incorrect syntax near '>'.
Msg 102, Level 15, State 1, Line 53
Incorrect syntax near 'Month'.
Msg 102, Level 15, State 1, Line 54
Incorrect syntax near 'Month'.

Og hele SQL er sådan her:

Declare @LedgerAccount varchar(8)
Declare @FiscalYear int
Declare @FiscalMonth int

SELECT
              [OrderID]
              ,[CustomerID]
              ,[CustomerName]
              ,[CustomerCountry]
              ,[OfficeID]
              ,[OfficeName]
              ,[PartnerID]
              ,[PartnerName]
              ,[OrderID]
              ,[Expiration]
              ,[LicenseID]
              ,SUM([RetailTotal]) as RetailTotal
              ,SUM([PartnerTotal]) as PartnerTotal
              ,SUM([OfficeTotal]) as Officetotal
              ,[InvoiceDate]
              ,@LedgerAccount = (CASE WHEN LedgerAccount IS NULL THEN
                    (CASE
                          WHEN [OrderLineType] = 'product' THEN '1010'
                            WHEN [OrderLineType] = 'maintenance' AND [Expiration] > [InvoiceDate] + 540 THEN 'LTM1020'
                          WHEN [OrderLineType] = 'upgrade' AND [Expiration] IS NOT NULL THEN '1020'
                          WHEN [OrderLineType] = 'upgrade' THEN '1010'
                          WHEN [OrderLineType] = 'maintenance' THEN '1020'
                          ELSE [OrderLineType]
                    END)
              ELSE
                    LedgerAccount
              END
              ) as LedgerAccount
              ,(CASE WHEN
                                  OrderId = LicenseId
                                  AND LedgerAccount = 1020
                                  AND SUM([RetailTotal]) > 0
                                  AND (SELECT SUM(RetailTotal) FROM [LicenseAnalysis].[dbo].[OrderDetails] as P2 WHERE P2.OrderId = P1.OrderId AND P2.LedgerAccount = 1010)  > 0
                          THEN 1
                          ELSE 0
                          END) as FirstYearMaintenance
                         
              ,(CASE WHEN
                                  OrderId = LicenseId
                                  AND LedgerAccount = 1020
                                  AND SUM([RetailTotal]) > 0
                                  AND (SELECT SUM(RetailTotal) FROM [LicenseAnalysis].[dbo].[OrderDetails] as P2 WHERE P2.OrderId = P1.OrderId AND P2.LedgerAccount = 1010)  > 0
                          THEN '1010'
                          Else @LedgerAccount END) as calcLedger
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN YEAR(InvoiceDate) ELSE 0 END) as Year
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN MONTH(InvoiceDate) ELSE 0 END) as Month
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN YEAR(InvoiceDate)-1+FLOOR(MONTH(InvoiceDate)/7) ELSE 0 END) as FiscalYear
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN FLOOR(((Month(InvoiceDate)+5) % 12)/3+1) ELSE 0 END) as FiscalQuarter
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN (((Month(InvoiceDate)+5) % 12)+1) ELSE 0 END) as FiscalMonth

  FROM [LicenseAnalysis].[dbo].[OrderDetails] as P1
  WHERE [InvoiceDate] > '20120630'
  GROUP BY [OrderID]
                ,[LedgerAccount]
                ,[OrderLineType]
                ,[Expiration]
                ,[CustomerID]
                ,[CustomerName]
                ,[CustomerCountry]
                ,[OfficeID]
                ,[OfficeName]
                ,[PartnerID]
                ,[PartnerName]
                ,[OrderID]
                ,[Expiration]
                ,[LicenseID]
                ,[InvoiceDate]
Avatar billede Syska Mester
05. december 2013 - 09:07 #6
Nu giver det hele lidt mere mening.

Du kan ikke både assign en variable og select den.

Her er det tilrettet SQL:
Declare @LedgerAccount varchar(8)
Declare @FiscalYear int
Declare @FiscalMonth int

SELECT
              [OrderID]
              ,[CustomerID]
              ,[CustomerName]
              ,[CustomerCountry]
              ,[OfficeID]
              ,[OfficeName]
              ,[PartnerID]
              ,[PartnerName]
              ,[OrderID]
              ,[Expiration]
              ,[LicenseID]
              ,SUM([RetailTotal]) as RetailTotal
              ,SUM([PartnerTotal]) as PartnerTotal
              ,SUM([OfficeTotal]) as Officetotal
              ,[InvoiceDate]
              ,@LedgerAccount = (CASE WHEN LedgerAccount IS NULL THEN
                    (CASE
                          WHEN [OrderLineType] = 'product' THEN '1010'
                            WHEN [OrderLineType] = 'maintenance' AND [Expiration] > [InvoiceDate] + 540 THEN 'LTM1020'
                          WHEN [OrderLineType] = 'upgrade' AND [Expiration] IS NOT NULL THEN '1020'
                          WHEN [OrderLineType] = 'upgrade' THEN '1010'
                          WHEN [OrderLineType] = 'maintenance' THEN '1020'
                          ELSE [OrderLineType]
                    END)
              ELSE
                    LedgerAccount
              END
              )
              ,(CASE WHEN
                                  OrderId = LicenseId
                                  AND LedgerAccount = 1020
                                  AND SUM([RetailTotal]) > 0
                                  AND (SELECT SUM(RetailTotal) FROM [LicenseAnalysis].[dbo].[OrderDetails] as P2 WHERE P2.OrderId = P1.OrderId AND P2.LedgerAccount = 1010)  > 0
                          THEN 1
                          ELSE 0
                          END) as FirstYearMaintenance
                         
              ,(CASE WHEN
                                  OrderId = LicenseId
                                  AND LedgerAccount = 1020
                                  AND SUM([RetailTotal]) > 0
                                  AND (SELECT SUM(RetailTotal) FROM [LicenseAnalysis].[dbo].[OrderDetails] as P2 WHERE P2.OrderId = P1.OrderId AND P2.LedgerAccount = 1010)  > 0
                          THEN '1010'
                          Else @LedgerAccount END) as calcLedger
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN YEAR(InvoiceDate) ELSE 0 END) as Year
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN MONTH(InvoiceDate) ELSE 0 END) as Month
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN YEAR(InvoiceDate)-1+FLOOR(MONTH(InvoiceDate)/7) ELSE 0 END) as FiscalYear
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN FLOOR(((Month(InvoiceDate)+5) % 12)/3+1) ELSE 0 END) as FiscalQuarter
            ,(CASE WHEN InvoiceDate IS NOT NULL THEN (((Month(InvoiceDate)+5) % 12)+1) ELSE 0 END) as FiscalMonth

  FROM [LicenseAnalysis].[dbo].[OrderDetails] as P1
  WHERE [InvoiceDate] > '20120630'
  GROUP BY [OrderID]
                ,[LedgerAccount]
                ,[OrderLineType]
                ,[Expiration]
                ,[CustomerID]
                ,[CustomerName]
                ,[CustomerCountry]
                ,[OfficeID]
                ,[OfficeName]
                ,[PartnerID]
                ,[PartnerName]
                ,[OrderID]
                ,[Expiration]
                ,[LicenseID]
                ,[InvoiceDate]


Udover det ... så kommer den fejl jeg snakker om nu:
Msg 141, Level 15, State 1, Line 5
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.


Ergo, noget der returnere mere end 1 row kan ikke bruges hvis du laver en assignment i din SQL query.

Du kan heller ikke bruger en variable i samme query hvor du har assigned den.

Du kan måske lave en SQL Function(http://technet.microsoft.com/en-us/library/aa214363(v=sql.80).aspx), hvor at genbruge samme logik til at regne den ud med.
Avatar billede Slettet bruger
05. december 2013 - 14:19 #7
Hej

Tak for input, men jeg er sgu helt blank på det. Jeg har rodet lidt frem og tilbage, men kan ikke få noget til at give mening.

Kan du uddybe lidt mere, hvad du tænker?
Avatar billede Syska Mester
05. december 2013 - 15:13 #8
I stedet for at henvise til en variable bliver du nød til at indsætte samme logik længere nede i din SQL Query.

Alt i din select bliver kørt på samme tid, dvs at du ikke kan henvise til andre ting i din select query.

Derfor bliver du nødt til at have samme logik flere gange hvilket selvf kan være dumt, men der er ingen vej udenom.

Hvad du måske kan gøre er at pakke det ind i en funktion, ligesom man kan i Excel med Macros og andet for at genbruge sin logik flere steder. Jeg er dog ikke klar over hvad din baggrund er, så ved ikke hvor meget forklaring der er brug for.
Avatar billede Slettet bruger
23. oktober 2014 - 11:36 #9
Tak.
Avatar billede Slettet bruger
23. oktober 2014 - 11:36 #10
Ups.
Avatar billede Slettet bruger
23. oktober 2014 - 11:37 #11
Buzzz - jeg ville have givet dig point. Beklager at dennne tråd døde lidt for mig. Tak for hjælpen.
Avatar billede Syska Mester
23. oktober 2014 - 20:32 #12
Svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester