webForumDet fria alternativet
Logga in / Bli medlem

sp Order By dynamiskt

Databaser & SQL

12 svar · 224 visningar · startad av KalsongCesar

Medlem sedan mars 2001339 inlägg
Trådstart#1

har läst och hittat ngr svar här men de hjälpte inte mig.

Jag vill skicka med en variabel i min sp som styr vad som ska sorteras efter.
orginal

CREATE PROCEDURE spListUserPay2 
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY Users.expiryDate DESC
GO

nu har jag provat med att lägga till min variabel. men det går inte..

CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY @sort
GO

Kollade lite på en annan fråga som körde en select och vid vissa case casta om men det fick jag inte heller till..

Ngn som har lite tid över?

Medlem sedan dec. 200012 464 inlägg
#2

Eftersom du har distinct så kan du bara sortera på sådant som finns med i select-listan.

Om @sort innehåller kolumnnamn så:

CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad,
               case @sort when 'Title' then title
                                  when 'Name' then name end
                        as sort
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL
ORDER BY sort
GO

Det går så länge alla kolumner som du vill sortera på är av samma datatyp.

Medlem sedan mars 2001339 inlägg
#3

oki.. det verkar ju logiskt, men jag får inte ens skapa min sp det blir error 1008

Medlem sedan dec. 200012 464 inlägg
#4

1008 just det ja, jag förstår ... inte.

Vad är feltexten och hur ser proceduren ut?

Medlem sedan mars 2001339 inlägg
#5

Error 1008: The SELECT item identified by the ORDER BY number 1 contains a variable as part of the expression identifying a column position. Variables are only allowed when ordering by an expression referencing a column name
=)

Medlem sedan dec. 200012 464 inlägg
#6
CREATE PROCEDURE spListUserPay2 
@sort as varchar(20)
AS
select * from (
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate = NULL) s
ORDER BY case @sort when 'Title' then title
                                  when 'Name' then name end
Medlem sedan mars 2001339 inlägg
#7

tack, jag provade din lösning, som jag även sett på ett annat fall här, åxå testat med cast för att få den till varchar men ingen förbättring. Det som händer nu är att den säger att fältet måste finnas med om distinct används.

Medlem sedan dec. 200012 464 inlägg
#8

Måste du ha distinct då?

Medlem sedan mars 2001339 inlägg
#9

ja, jag väljer ut en person och dennes fakturor.. har den fler så vill jag inte få upp honnom flera ggr på listan.

Medlem sedan dec. 200012 464 inlägg
#10

oki, nytt förslag

if @sort = 'Title' 

SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL
order by title
else if @sort = 'Name' 
SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL
order by name

Jag ändrade från = NULL till is NULL också.

Ett annat alternativ är att skapa en sträng som innehåller frågan

@declare str varchar(2000)
set @str = 'SELECT   	DISTINCT Users.idxUser,
		Users.Title, 
		Users.Name, 
		Users.SurName, 	
		Users.BusinessName, 
		Users.Address1, 
                      	Users.Address2, 
		Users.Address3, 
		Users.City, 
		Users.PostCode, 
		Users.Email, 
		Users.expiryDate, 
		Users.betalatAbb, 
                      	Users.tempAccess, 
		Users.campaign, 
		Users.abonnemang,
		abonnemangstyper.beskrivning,
		Users.CreatedDate, 
		Campaigns.Name AS CampaignName, Campaigns.Months, 
                      Users.hantering, Invoice.Makulerad
FROM         Users INNER JOIN
                      abonnemangstyper ON abonnemangstyper.idxAbonnemang = Users.abonnemang INNER JOIN
                      Invoice ON Users.idxUser = Invoice.idxUser LEFT OUTER JOIN
                     Campaigns ON Users.idxCampaign = Campaigns.idxCampaign
WHERE     (Users.accepted = 1)  AND (Invoice.Makulerad = 0) AND Invoice.Paydate is NULL order by ' + @sort
exec (@str)
Medlem sedan mars 2001339 inlägg
#11

Ska testa pronto imorgon bitti.. tack, dags att dra iväg..

Medlem sedan dec. 200012 464 inlägg
#12

För att slippa distinct så borde du kunna byta ut någon av dina joinar mot en korrelerad subquery (Eftersom jag inte orkar göra en begåvad gissning om din tabellstruktur så gör jag ett generellt exempel.)

select distint t1.c1,t1.c2 from t1 inner join t2 on t1.id  = t2.id

kan bytas mot

select c1,c2 from t1
where exists (select * from t2 where id = t1.id)

som förmodligen är effektivare också.

Medlem sedan mars 2001339 inlägg
#13

funkade fint att ha if satsen som kollade strängen.... nöjer med det så länge.. men vem vet, kanske kommer tillbaka till tråden snabbare än jag trott ;)

269 ms totalt · 4 externa anrop · v20260731065814-full.7d626504
126 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)