Avatar billede Ulrich Seniormester
15. februar 2018 - 21:01 Der er 20 kommentarer

SQL streng der læser flere kolonner på samme tid og laver SUM.

Her en MS database som indeholder medlems numre, om aktivitet er tildelt, og om den er betalt.
Er det muligt at lave en SQL streng der giver en SUM ud fra følgende:
Ser om Aktx er = checked og efterfølgende om AktxBetalt står 2018 = ok skal tælles med i SUM.
Aktx er = checked og Aktx Betalt ikke = 2018 = ikke ok skal ikke tælles med i SUM.

Udfordringen er at SQL streng skal se på Akt1, Akt2, Akt3 osv er = checked og Akt1Betalt, Akt2Betalt, Akt3Betalt osv er = 2018, SUM en op ellers tæl den ikke med for Medlemsnummer 1 og der efter det samme for Medlemsnummer 2.... osv.
Kn og har lavet det i en løkke, men der er MANGE records og MANGE Aktx så det tager LANG tid med en løkke.

Medlemsnummer    Akt1            Akt2    Akt3     Akt4     Akt5            Akt1Betalt    Akt2Betalt    Akt3Betalt    Akt4Betalt    Akt5Betalt
1                            checked                                                      2018               
2                          checked            checked                                                            2018                        2017
4                          checked                                                                                                    2018               
5                          checked                                        checked                              2011                                                    2018
Avatar billede Rune1983 Ekspert
16. februar 2018 - 10:03 #1
Skal data forstået på denne måde?
Medlemsnummer Akt1 Akt2 Akt3 Akt4 Akt5 Akt1Betalt Akt2Betalt Akt3Betalt Akt4Betalt Akt5Betalt
1 checked - - - - 2018 - - - -
2 checked checked - - - 2018 2017 - - -
4 checked - - - - 2018 - - - -
5 checked - - - checked 2011 - - - 2018
Avatar billede Ulrich Seniormester
16. februar 2018 - 11:30 #2
Hej. Ja det er rigtigt forstået.
Kan også forekomme at Akt1 ikke er checked.
Avatar billede Rune1983 Ekspert
16. februar 2018 - 12:03 #3
Så få databaseudtræk til at tælle antal hvor
aktX = checked
aktXBetalt = 2018
=> +1 til Antal

Resultat af udtræk nedenfor.
Medlemsnummer Akt1 Akt2 Akt3 Akt4 Akt5 Akt1Betalt Akt2Betalt Akt3Betalt Akt4Betalt Akt5Betalt Antal
1 checked - - - - 2018 - - - - 1
2 checked checked - - - 2018 2018 - - - 2
4 checked - checked checked - - 2018 - 2018 2018 - - 3
5 checked - - - checked 2011 - - - 2018 1

Er det sådan du ønsker?
Avatar billede Ulrich Seniormester
16. februar 2018 - 16:31 #4
Både ja og nej. Har været en checked i en Aktx og en 2018 i AktxBetalt skal den tælle for 1.
Kommer der flere 2018 eller flere checked skal den stadig kun tælle 1.
Ingen checked = ingen +1 til Antal.
1 checked - - - - 2018 - - - - 1
2 - checked - - - 2018 2018 - - - 1
4 checked - checked checked - - 2016 - 2018 2018 - - 1
5 checked - - - checked 2011 - - - 2018 1
6 - - - - - - - - - - 0
7 checked - - - checked 2011 - - - 2017 0
8 - - - -  - -- - - 2018 0
Der skal forekomme en checked et sted i Aktx og en 2018 i AktxBetalt før der tælles op +1 til Antal.
Avatar billede Slettet bruger
19. februar 2018 - 08:44 #5
Kan du ligge et billede op som viser den rigtige dataopstilling? Ret svært at gennemskue med formatteringen herinde. Evt som dit data ser ud og forventet resultat? Vil tror du kan løse det med noget case when og en sum
Avatar billede Slettet bruger
19. februar 2018 - 09:01 #6
Vil det her give dig det rigtige?

Du kan bare summe den bagefter og group på medlemdsnummer i en subselect bagefter evt.

Så vidt jeg lige kan lure, så skal du bare tælle 1 hver gang der er en forekomst af aktx = checked og aktxbetalt = 2018.


declare @myt table (Medlemsnummer int, akt1 nvarchar(50),akt2 nvarchar(50),akt3 nvarchar(50),akt4 nvarchar(50),akt5 nvarchar(50),Akt1Betalt int,Akt2Betalt int
,Akt3Betalt int ,Akt4Betalt int ,Akt5Betalt int)

insert into @myt

values

(1, 'checked','None'  ,'None','None','None' ,2018 ,1900,1900,1900,1900),
(2, 'checked','checked','None','None','None' ,2018, 2017,1900,1900,1900),
(4, 'checked','None'  ,'None','None','None' ,2018,1900,1900,1900,1900),
(5, 'checked','None'  ,'None','None','checked' ,2011,1900,1900,2017, 2017)


select * ,
case when (akt1 = 'checked' and Akt1Betalt = 2018) then 1
when (akt2 = 'checked' and Akt2Betalt = 2018) then 1
when (akt3 = 'checked' and Akt3Betalt = 2018) then 1
when (akt4 = 'checked' and Akt4Betalt = 2018) then 1
when (akt5 = 'checked' and Akt5Betalt = 2018) then 1 else 0 end as Nom

from @myt
Avatar billede Ulrich Seniormester
19. februar 2018 - 20:25 #7
Det ser meget rigtigt ud, men jeg kan ikke få det til at virke på min .asp side.
Det er .mdb MSSQL jeg kører:

("select *, case when (akt1 = 'checked' and Akt1Betalt = '2018') then '1' when (akt2 = 'checked' and Akt2Betalt = '2018') then '1' when (akt3 = 'checked' and Akt3Betalt = '2018') then '1' else '0' end as Nom from Adresseliste")

Men den vil ikke acceptere det.
Avatar billede Slettet bruger
19. februar 2018 - 20:57 #8
Du skal bruge IIF funktionen istedet for case when så. Det er nok fordi case when ikke virker til .mdb.. JEg prøver lige at skrive funktionen i morgen når jeg er på arbejde. Kan ikke lige gennemskue uden mangement studio
Avatar billede Slettet bruger
19. februar 2018 - 21:22 #9
SELECT
  IIF(test_expression, value_if_true, value_if_false) AS FIELD_NAME
FROM
  TABLE_NAME
Avatar billede Slettet bruger
20. februar 2018 - 10:45 #10
Her er løsning med IIF expression i stedet. prøv det

declare @myt table (Medlemsnummer int, akt1 nvarchar(50),akt2 nvarchar(50),akt3 nvarchar(50),akt4 nvarchar(50),akt5 nvarchar(50),Akt1Betalt int,Akt2Betalt int
,Akt3Betalt int ,Akt4Betalt int ,Akt5Betalt int)

insert into @myt

values

(1, 'checked','None'  ,'None','None','None' ,2018 ,1900,1900,1900,1900),
(2, 'checked','checked','None','None','None' ,2018, 2017,1900,1900,1900),
(4, 'checked','None'  ,'None','None','None' ,2018,1900,1900,1900,1900),
(5, 'checked','None'  ,'None','None','checked' ,2011,2018,1900,2017, 2017)


select * ,
IIF(akt1 = 'checked' and Akt1Betalt = 2018,1,
IIF(akt2 = 'checked' and Akt2Betalt = 2018,1,
IIF(akt3 = 'checked' and Akt3Betalt = 2018,1,
IIF(akt4 = 'checked' and Akt4Betalt = 2018,1,
IIF(akt5 = 'checked' and Akt5Betalt = 2018,1,0))))) as Nom

from @myt
Avatar billede Ulrich Seniormester
20. februar 2018 - 18:03 #11
Nu kan jeg få strengen til at virke, men den tæller ikke helt som den skal.
Her er det jeg bruger nu, men det tager for lang tid, derfor er jeg ude efter en SQL streng der kan gøre det:

T=0
AntalBetaltForAarTilbage.movefirst
Do while not AntalBetaltForAarTilbage.EOF
BetaltStatus = "True"
For y = 1 to 40
  If AntalBetaltForAarTilbage("Akt" & y) = "checked" Then
  If Ucase(Trim(AntalBetaltForAarTilbage("Akt" & y & "Betalt"))) = "2018" Then
  BetaltStatus = "False"
  End If
  End If
Next
If BetaltStatus = "False" Then
T=T+1
End If
AntalBetaltForAarTilbage.movenext
loop

response.write(T)
Avatar billede Slettet bruger
20. februar 2018 - 19:42 #12
Kan du beskrive hvad du mnagler? Jeg forstår ikke helt 100 hvad du er ude efter hvis den ikke blot skal tælle 1 hver gang du har en  checked i en akt og denne tilhørende akt = 2018
Avatar billede Ulrich Seniormester
20. februar 2018 - 20:23 #13
En record indeholder Akt1 til Akt40 og Akt1Betalt til Akt40Betalt.
Hvis en record indeholder checked i en af de 40 Akt1 til 40 og der i en af de 40 Akt1Betalt til Akt40Betalt = 2018 så tælles der op med 1 (x=x+1) = 1

Hvis record nummer to indeholder checked i en af de 40 Akt1 til 40 og der i en af de 40 Akt1Betalt til Akt40Betalt = 2018 så tælles der op med 1 (x=x+1) = 2

Hvis fx record nummer tre indeholder checked i en af de 40 Akt1 til 40 og der i en af de 40 Akt1Betalt til Akt40Betalt = 2011 så tælles der IKKE op med 1 (x=x+1) forbliver = 2

Hvis fx record nummer fire IKKE indeholder checked i en af de 40 Akt1 til 40 og der i en af de 40 Akt1Betalt til Akt40Betalt = 2011 eller noget andet så tælles der IKKE op med 1 (x=x+1) forbliver = 2

Så hvis en record indeholder checked i bare en af de 40 Akt1 til 40 og der samtidigt i en af de 40 Akt1Betalt til Akt40Betalt = 2018 så tælles der op med 1 (x=x+1) altså x forøges hver gang.

1 checked - - - - 2018 - - - - x=x+1
2 - checked - - - 2018 2018 - - - x=x+1
4 checked - checked checked - - 2016 - 2018 2018 - - x=x+1
5 checked - - - checked 2011 - - - 2018 x=x+1
6 - - - - - - - - - - 0
7 checked - - - checked 2011 - - - 2017 0
8 - - - -  - -- - - 2018 0
Ovenstående giver SUM på x=4 og det er summen jeg skal bruge.
Avatar billede Slettet bruger
20. februar 2018 - 20:45 #14
Men det giver min jo også? Du skal bare summe den samme bagefter i en subselect

select sum(Nom) from (
select * ,
IIF(akt1 = 'checked' and Akt1Betalt = 2018,1,
IIF(akt2 = 'checked' and Akt2Betalt = 2018,1,
IIF(akt3 = 'checked' and Akt3Betalt = 2018,1,
IIF(akt4 = 'checked' and Akt4Betalt = 2018,1,
IIF(akt5 = 'checked' and Akt5Betalt = 2018,1,0))))) as Nom

from @myt
) x

Skal du have gruppereret på medlemsnummer skal du skrive det med i din select
Avatar billede Ulrich Seniormester
22. februar 2018 - 18:01 #15
Tror ikke helt jeg forstår.
Skal jeg bruge den sidste nye streng du her over har skrevet i stedet for den forrige?

Før fik jeg resultatet ud på følgende måde:
response.write(AntalOprettedeaa("Nom"))

Hvad gør jeg nu?

set AntalOprettedeaa = conn.execute("select * ,IIF(akt1 = 'checked' and Akt1Betalt = '2018',1,IIF(akt2 = 'checked' and Akt2Betalt = '2018',1,IIF(akt3 = 'checked' and Akt3Betalt = '2018',1,IIF(akt4 = 'checked' and Akt4Betalt = '2018',1,IIF(akt5 = 'checked' and Akt5Betalt = '2018',1,0))))) as Nom from Adresseliste")

set AntalOprettedebb = conn.execute("select sum(Nom) from (select * ,IIF(akt1 = 'checked' and Akt1Betalt = '2018',1,IIF(akt2 = 'checked' and Akt2Betalt = '2018',1,IIF(akt3 = 'checked' and Akt3Betalt = '2018',1,IIF(akt4 = 'checked' and Akt4Betalt = '2018',1,IIF(akt5 = 'checked' and Akt5Betalt = '2018',1,0))))) as Nom from Adresseliste)x")
Avatar billede Slettet bruger
26. februar 2018 - 10:42 #16
Er der stadig fejl? Den sidste giver dig summen som du gerne vil have ? Eller hvad?
Avatar billede Ulrich Seniormester
26. februar 2018 - 18:05 #17
Kan godt være det er mig der ikke helt forstår det, men kan ikke få den sidste til at give sum, den giver heller ikke fejl, så muligt jeg response.write noget forkert.

set AntalOprettedebb = conn.execute("select sum(Nom) from (select * ,IIF(akt1 = 'checked' and Akt1Betalt = '2018',1,IIF(akt2 = 'checked' and Akt2Betalt = '2018',1,IIF(akt3 = 'checked' and Akt3Betalt = '2018',1,IIF(akt4 = 'checked' and Akt4Betalt = '2018',1,IIF(akt5 = 'checked' and Akt5Betalt = '2018',1,0))))) as Nom from Adresseliste)x")

response.write(AntalOprettedebb("Nom"))
Avatar billede Slettet bruger
27. februar 2018 - 08:43 #18
Prøv at giv kolonnen et alias og se om det virker....

Select sum(Nom) as Antal from (select * osv osv
Avatar billede Slettet bruger
27. februar 2018 - 08:44 #19
Eller kald den Nom som du referer til i dit response write.
Avatar billede Ulrich Seniormester
01. marts 2018 - 18:21 #20
Hej det virker.
Dog er jeg løbet i det problem at jeg får : Expression too complex in query
Grunden er at jeg har Akt1 til Akt40 og Akt1Betalt til Akt40Betalt og det er for mange i en SQL streng.
Så kan ikke bruge strengen......
Øv..
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