Avatar billede simsen Mester
08. februar 2011 - 00:14 Der er 5 kommentarer og
1 løsning

Select med unique identifier ved null værdi

Hej,

Jeg har 3 tabeller med følgende kolonner

Chat_Message
...messageId
...UserId
...toUserId
Rækkerne ser ud på følgende måde
1...ff00....ff11
2...ff22....    (altså her står der intet i toUserId)

aspnet_Users_1 (som linker til UserId i Chat_Message)
...UserId
...UserName

aspnet_Users (som linker til toUserId i Chat_Message)
...UserId
...UserName

Det jeg vil have ud er alle rækker i Chat_Message med tilhørende navne for brugerne. Også selv om der intet står i toUserId - så skal navnet bare være null eller blank.....
Altså rækkerne skal se ud som følgende:
1...ff00....Hansen....ff11....Jensen
2...ff22....Larsen....NULL....NULL (altså her står der intet i toUserId)

Jeg har forsøgt med følgende:

SELECT    dbo.Chat_Message.messageId, dbo.Chat_Message.roomId, dbo.Chat_Message.UserId, aspnet_Users_1.UserName, dbo.Chat_Message.IPAddress,
                      dbo.Chat_Message.toUserId, dbo.Chat_Message.message, dbo.Chat_Message.timeStamp, dbo.Chat_Message.color,
                      dbo.aspnet_Users.UserName AS toUserName
FROM        dbo.Chat_Message INNER JOIN
                      dbo.aspnet_Users AS aspnet_Users_1 ON dbo.Chat_Message.UserId = aspnet_Users_1.UserId LEFT OUTER JOIN
                      dbo.aspnet_Users ON dbo.Chat_Message.toUserId = dbo.aspnet_Users.UserId

Men får nu så fejl, der siger:
"Error Message: Conversion failed when converting from a character string to uniqueidentifer"

Jeg er godt klar over det er den tomme plads i række to (altså ingen toUserId), der giver fejlen.....

Men jeg aner ikke hvordan jeg skal løse det - håber I kan hjælpe mig.

mvh
simsen :-)
08. februar 2011 - 07:55 #1
Din select skal teste om toUserId er null og saa enten vise null eller vise toUser's navn.

Men du goer det alt for indviklet.  Der er ingen grund til (og imod principperne for normaliserede databaser) at have to user-tabeller, og du kan goere din forespoergsel kortere og nemmere at overse ved at bruge aliaser i stedet for lange tabel navne. 

For at teste princippet med IF (som det er nogen tid siden jeg har brugt) gjorde jeg det foelgende:

Jeg arbejdede i MYSQL fordi jeg ikke har MSSQL, men det skulle virke der ogsaa.

Jeg lavede nedenstaaende to tabeller der kun rummer messageid, user-id'er og usernavne.

Og saa koerte jeg denne query:

SELECT m.id, m.user, u.name, m.toUser, IF(m.toUser IS NOT NULL, (SELECT name FROM simsen_user WHERE id = m.id), NULL) as toUserName FROM simsen_message m LEFT JOIN simsen_user u ON m.user = u.id;

som gav dette resultat:

id  user  name  toUser  toUserName 
1 1 Hansen 2 Hansen
2 1 Hansen 3 Jensen
3 2 Jensen 3 Svensen
4 2 Jensen 1 NULL
5 1 Hansen NULL NULL
6 2 Jensen NULL NULL

Her er de to tabeller:

CREATE TABLE simsen_message(id INT, user INT, toUser INT);

INSERT INTO simsen_message VALUES(1, 1, 2);
INSERT INTO simsen_message VALUES(2, 1, 3);
INSERT INTO simsen_message VALUES(3, 2, 3);
INSERT INTO simsen_message VALUES(4, 2, 1);
INSERT INTO simsen_message VALUES(5, 1, NULL);
INSERT INTO simsen_message VALUES(6, 2, NULL);

CREATE TABLE simsen_user(id INT, name VARCHAR(10));

INSERT INTO simsen_user VALUES(1, 'Hansen');
INSERT INTO simsen_user VALUES(2, 'Jensen');
INSERT INTO simsen_user VALUES(3, 'Svensen');
Avatar billede simsen Mester
09. februar 2011 - 15:59 #2
Hej Christian,

Tak for dit svar. Jeg kan desværre ikke få dit eksempel til at virke. Først så brugte du user som navn - den er et reserveret ord, så jeg ændrede den til userid - det samme med name ændrede jeg til username;

CREATE TABLE simsen_message(id INT, userId INT, toUser INT);

INSERT INTO simsen_message VALUES(1, 1, 2);
INSERT INTO simsen_message VALUES(2, 1, 3);
INSERT INTO simsen_message VALUES(3, 2, 3);
INSERT INTO simsen_message VALUES(4, 2, 1);
INSERT INTO simsen_message VALUES(5, 1, NULL);
INSERT INTO simsen_message VALUES(6, 2, NULL);

CREATE TABLE simsen_user(id INT, username VARCHAR(10));

INSERT INTO simsen_user VALUES(1, 'Hansen');
INSERT INTO simsen_user VALUES(2, 'Jensen');
INSERT INTO simsen_user VALUES(3, 'Svensen');

Så kørte jeg følgende SQL sætning i en forespørgsel:

SELECT m.id, m.userid, u.username, m.toUser,
IF(m.toUser IS NOT NULL, (SELECT username FROM simsen_user WHERE id = m.id), NULL) as toUserName
FROM simsen_message m LEFT JOIN simsen_user u ON m.userid = u.id;

Men får så følgende fejl meddelelse:
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'IF'.
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near ','.
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near ','

Jeg kan se at fejlene koncentrerer sig om IF statement linjen:

IF (m.toUser IS NOT NULL, (SELECT username FROM simsen_user WHERE id = m.id), NULL) as toUserName

Jeg kan bare ikke se hvor det går galt?
Avatar billede simsen Mester
09. februar 2011 - 16:04 #3
Hov en anden ting. Jeg har forsøgt mig med følgende i IF sætningen - fordi den giver mig mere mening - at jeg skal lave en where på id = m.toUser - det er jo toUser jeg vil hente navnet på. Eller tænker jeg bare ikke logisk?

SELECT m.id, m.userid, u.username, m.toUser,
IF (m.toUser IS NOT NULL, (SELECT username FROM simsen_user WHERE id = m.toUser), NULL) as toUserName
FROM simsen_message m LEFT JOIN simsen_user u ON m.userid = u.id;
09. februar 2011 - 21:46 #4
Problemet skyldes at jeg nok skal have nye briller!  Jeg bruger Mysql, og jeg udarbejdede og testede mit svar i en Mysql database skoent dit spoergsmaal hoejt og tydeligt er oprettet i MSSQL kategorien.

Jeg googlede rundt - saa vidt jeg kan se (men jeg har ikke mulighed for at afproeve det) har MSSQL en IIF funktion der goer det samme som IF funktionen i Mysql.  Se for eksempel http://forums.devx.com/archive/index.php/t-23457.html.  Proev engang med denne query:

SELECT m.id, m.userid, u.username, m.toUser,
IIF(m.toUser IS NOT NULL, (SELECT username FROM simsen_user WHERE id = m.id), NULL) as toUserName
FROM simsen_message m LEFT JOIN simsen_user u ON m.userid = u.id;

Hvis det virker saa, hurra,  virker det.  Hvis det ikke virker maa vi soege videre.  (Eller maaske kender et andet Eksperten medlem loesningen.)

Jeg venter med at kikke paa #3 til vi ser om IIF virker.  Microsoft Access har en IIF metode, IIF for 'Immediate IF', saa det er taenkeligt at Microsofts MSSQL ogsaa bruger IIF.
Avatar billede simsen Mester
09. februar 2011 - 22:24 #5
Jeg bliver nødt til at have mere hjælp :-)
Den har ikke en IIF - men har så været ude og google og er måske kommet frem til, jeg skal bruge CASE WHEN istedet;

http://msdn.microsoft.com/en-us/library/ms181765.aspx

Men jeg kan ikke hitte ud af det....

Jeg har følgende select statement for nuværende;

SELECT m.id, m.userid, u.username, m.toUser,
CASE WHEN m.toUser IS NOT NULL THEN (SELECT u.userName FROM simsen_user WHERE id = m.toUser) ELSE NULL END AS toUserName
FROM simsen_message m LEFT JOIN simsen_user u ON m.userid = u.id;

Det giver ingen fejl - men heller ikke resultatet - det der kommer ud er;

1 1 Hansen 2 Hansen
2 1 Hansen 3 Hansen
3 2 Jensen 3 Jensen
4 2 Jensen 1 Jensen
5 1 Hansen NULL NULL
6 2 Jensen NULL NULL
5
Avatar billede simsen Mester
09. februar 2011 - 22:31 #6
YES - har fundet ud af det nu........

SELECT m.id, m.userid, u.username, m.toUser,
CASE WHEN m.toUser IS NOT NULL THEN (SELECT userName FROM simsen_user WHERE id = m.toUser) ELSE NULL END AS toUserName
FROM simsen_message m LEFT JOIN simsen_user u ON m.userid = u.id;

Jeg fjernede u. i select i case delen......

Rigtig mange gange tak for hjælpen - havde aldrig klaret den, hvis du ikke havde ledt mig på rette spor :-)
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