Avatar billede madeindk Nybegynder
30. oktober 2009 - 00:10 Der er 11 kommentarer og
1 løsning

Problemer med CTE, UNION ALL og ORDER BY

Hej eksperter, jeg er i gang med at lave en CTE - den driller mig desværre rimelig meget, da jeg har fundet ud af at man ikke kan sortere på den anden SELECT i en UNION ALL, og det har jeg ret meget brug for.

Min menustruktur kan se cirka sådan her ud:

  - Hovedside 1 (1)
    - Underside 1 (1)
    - Underside 2 (2)
    - Underside 3 (3)
      - Underunderside 1 (1)
      - Underunderside 2 (2)
  Hovedside 2 (2)
    - Underside 1 (1)
    - Underside 2 (2)
    - Underside 3 (3)

Det er sorteringstallet der står i parentes, og den skal sortere som overstående, men det vil den ikke rigtig.

Lige i øjeblikket ser min SQL sådan her ud:

BEGIN
    -- Loop menuitems
    WITH temp_entries (page_id, parent_id, pagename, deactive, hidden, startpage, page_order, page_level) AS
    (
            SELECT TOP 100 s.id AS page_id, s.parent_id, s.pagename, s.is_deactive, s.is_hidden, s.is_startpage, s.page_order, 1 AS page_level
            FROM cms_menuitems s
            WHERE
                s.parent_id = 0
                AND
                s.language_id = @language_id
            ORDER BY s.page_order
                           
        UNION ALL
               
            SELECT s.id AS page_id, s.parent_id, s.pagename, s.is_deactive, s.is_hidden, s.is_startpage, s.page_order, t.page_level+1
            FROM cms_menuitems s, temp_entries t
            WHERE
                s.language_id = @language_id
                AND
                s.parent_id = t.page_id
    )
    -- Print menuitems
    SELECT page_id, parent_id, pagename, deactive, hidden, startpage, page_order, page_level FROM temp_entries ORDER BY page_order
END
Avatar billede janus_007 Nybegynder
30. oktober 2009 - 00:14 #1
Hvilken sql server version kører du?
Avatar billede madeindk Nybegynder
30. oktober 2009 - 08:19 #2
Jeg kører med MS SQL Server 2008.
Avatar billede hrc Mester
30. oktober 2009 - 13:10 #3
Jeg er med på en lytter (for andre der ikke ved hvad en CTE er: http://msdn.microsoft.com/en-us/magazine/cc163346.aspx)
Avatar billede hrc Mester
30. oktober 2009 - 14:27 #4
... Nå det ser ud til du har hentet eksemplet derfra. Jeg kan få det her til at virke - og det adskiller sig fra dit er ved jeg selekterer fra toppen og sorterer på [niveau] før [orden]

CREATE TABLE [dbo].[menu](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [parent_menu_id] [int] NULL,
    [navn] [varchar](50) NULL,
    [orden] [int] NULL,
CONSTRAINT [PK_menu] PRIMARY KEY CLUSTERED
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[menu] ON
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (1, NULL, N'Hovedside 1', 1)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (2, NULL, N'Hovedside 2', 2)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (3, 1, N'Underside 1_1', 1)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (4, 1, N'Underside 1_2', 2)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (5, 1, N'Underside 1_3', 3)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (6, 5, N'Underunderside 1_3_1', 1)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (7, 5, N'Underunderside 1_3_2', 2)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (8, 2, N'Underside 2_1', 1)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (9, 2, N'Underside 2_2', 2)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (10, 2, N'Underside 2_3', 3)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (11, 2, N'Underside 2_5', 5)
INSERT [dbo].[menu] ([id], [parent_menu_id], [navn], [orden]) VALUES (12, 2, N'Underside 2_4', 4)
SET IDENTITY_INSERT [dbo].[menu] OFF

/****** Object:  ForeignKey [FK_menu_menu]    Script Date: 10/30/2009 14:23:57 ******/
ALTER TABLE [dbo].[menu]  WITH CHECK ADD  CONSTRAINT [FK_menu_menu] FOREIGN KEY([parent_menu_id])
REFERENCES [dbo].[menu] ([id])
GO
ALTER TABLE [dbo].[menu] CHECK CONSTRAINT [FK_menu_menu]
GO


;WITH ItemsCTE([id], [parent_menu_id], [navn], [orden], [niveau]) AS
(
  SELECT [id], [parent_menu_id], [navn], [orden], 0
  FROM menu
  where ([id] = 1)
                         
  UNION ALL
             
  SELECT m.[id], m.[parent_menu_id], m.[navn], m.[orden], [niveau] + 1
  FROM menu m
  JOIN ItemsCTE mi on (mi.[id] = m.[parent_menu_id])
)
SELECT [id], [parent_menu_id], [navn], [orden], [niveau]
FROM ItemsCTE
order by [niveau], [orden]
Avatar billede hrc Mester
30. oktober 2009 - 14:35 #5
Nå, med lidt flere data i tabellen virker det ikke alligevel
Avatar billede madeindk Nybegynder
30. oktober 2009 - 14:39 #6
Nej, lige præcis - desværre ikke :(
Har selv været ude i den der løsning.
Avatar billede hrc Mester
30. oktober 2009 - 14:42 #7
Har du overvejet at lave det som en table-valued funktion?
Avatar billede janus_007 Nybegynder
31. oktober 2009 - 01:05 #8
Hvis du kører 2008 så skulle du kigge nærmere på hierarchyid :)
Avatar billede madeindk Nybegynder
31. oktober 2009 - 12:59 #9
Det siger mig umiddelbart ikke noget, har du noget eksempel på det Janus?
Avatar billede hrc Mester
31. oktober 2009 - 21:51 #10
Synes godt Janus kunne komme med lidt kildehenvisning. Du kan kigge her: http://msdn.microsoft.com/en-us/library/bb677290.aspx
Avatar billede hrc Mester
31. oktober 2009 - 22:19 #11
http://msdn.microsoft.com/en-us/library/bb677212%28lightweight%29.aspx.

Skal lige læse det et par gange før jeg forstår det; er meget abstrakt lige nu.
Avatar billede madeindk Nybegynder
17. november 2009 - 13:05 #12
Lukker, fandt aldrig en ordentlig løsning :(
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



IT-JOB