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
Kategori
Computerworld tilbyder specialiserede kurser i database-management

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