"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

MSSQL Join Probleme

Umlüx 24.02.2015 - 13:52 3928 18
Posts

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
und wieder eine dumme frage von mir :)
ich hab hier einen ganz einfachen mssql join
Code: SQL
SELECT * FROM Table_A a
INNER JOIN Table_B b
ON a.key = b.key
es könnte aber vorkommen, dass es in Table_B mehrere einträge mit dem key gibt. wie bekomm ich es am einfachsten hin, dass mir der join nur den letzten liefert statt allen?

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
Code: SQL
SELECT DISTINCT a.* FROM Table_B b
INNER JOIN Table_A a
ON a.key = b.key

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
sorry aber ich versteh nicht was mir das bringt? als erstes würden mir schonmal alle B werte fehlen. die brauche ich ja wohl auch. aber halt nur die letzten (aktuellsten)

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
stimmt, wird wohl nur über eine subquery gehen die dir jeden join wert der Tabelle B einmal rausgibt und dann mit dem A Table joinen

http://stackoverflow.com/questions/...in-to-first-row
Bearbeitet von Punisher am 24.02.2015, 15:28

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
irgendwie bin ich zu dumm bzw unerfahren dazu es hinzubekommen :( besonders da ich mit LIKE oder SUBSTRING arbeiten muss (ausser es gibt eine bessere lösung?)
einen key "abdc" aus Table_A müsst ich nämlich mit "abcd_1" oder "abcd_2" in Tabe_B matchen können. wobei ich immer nur den aktuellen (höchsten) wert haben will.

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
wieso brauchst du ein LIKE wenn du den selben key matchen musst (a.key = b.key)?

kannst du bitte mal 2-3 datensätze beider tabellen angeben (anonymisiert etc), und dann beschreiben wie sie gematcht werden sollen

edit

hab grad das selbe mit players & games nachgestellt

Code: SQL
SELECT players.FIRSTNAME, players.ID, games.ID, games.GAMEDATE 
FROM     players 
JOIN     games 
ON       games.id =          
            (SELECT  games.ID          
             FROM    games          
             WHERE   games.PLAYER_ID_1 = players.ID              
             LIMIT 1)
Code:
-- players
ID 		int(11) 	NO 	PRI 	NULL	auto_increment
FIRSTNAME 	varchar(30) 	NO 		NULL	
LASTNAME 	varchar(30) 	NO 		NULL	
RANK 		int(11) 	NO 		0 	
nick 		varchar(50) 	YES 		NULL

-- games
ID 			int(11) 	NO 	PRI 	NULL	auto_increment
GAMEDATE 		timestamp 	NO 		CURRENT_TIMESTAMP 	
PLAYER_ID_1 		int(11) 	NO 		NULL	
PLAYER_ID_2 		int(11) 	NO 		NULL	
LEGS_WON_PLAYER_1 	int(11) 	NO 		NULL	
LEGS_WON_PLAYER_2 	int(11) 	NO 		NULL

-- output (ein game pro spieler, obwohl viele in der db sind)
Richard 	1 	3 	2015-01-23 17:14:44
Christian 	2 	16 	2015-01-29 16:24:12
Vedran 		3 	11 	2015-01-28 16:49:09
Daniel 		4 	4 	2015-01-26 10:10:27
Daniel 		5 	5 	2015-01-26 14:59:58
Andreas 	6 	28 	2015-02-02 15:00:52
Gregor 		7 	27 	2015-02-02 15:00:39
Arno 		10 	79 	2015-02-18 15:05:47
Andreas 	11 	10 	2015-01-28 12:43:54
Karl 		12 	38 	2015-02-03 17:19:00
Johann 		13 	12 	2015-01-29 08:55:42
Stefan 		14 	23 	2015-02-02 09:45:51
Manuel 		15 	44 	2015-02-05 10:24:21
Bearbeitet von Punisher am 25.02.2015, 13:38

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
ja das kommt eh hin.
like bzw substring brauch ich, da das format von games.PLAYER_ID_1 nicht exakt players.ID entspricht. aber das ist eigentlich nicht das problem

das problem ist, hier bekomm ich alle games von einem gesuchten player.
wie mach ich die abfrage, wenn ich nur die zuletzt hinzugefügten games aller player sehen will? oder alle games, die alle player z.b. im dezember gekauft haben?
geht das überhaupt mit nur einer abfrage? oder sitz ich grad komplett auf der leitung.. :D

ich hab heut echt denkprobleme. ok nochmal von vorne. sagen wir, die tabellen sehen so aus.

Code:
Name    Game
Harald  2
Paul    3
Hugo    1
Harald  4

Game  Name  DLC
1     GTA
2     FC4
3     SC2
4     D3
4     D3    ROS

wenn ich wissen will was harald spielt und ich joine über Game, bekomm ich 2 results richtig? ich will aber nur den aktuellsten haben. in dem fall den mit dem ROS addon.
Bearbeitet von Umlüx am 25.02.2015, 13:45

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
das macht die subquery ... die gibt dir ein game für jeden player aus (LIMIT 1), mit einem order by kannst auch noch auf das letzte kommen
Code: SQL
SELECT players.FIRSTNAME, players.ID, games.ID, games.GAMEDATE 
FROM players 
JOIN games 
ON games.id = 
(SELECT games.ID 
FROM games 
WHERE games.PLAYER_ID_1 = players.ID 
ORDER BY games.GAMEDATE 
LIMIT 1)

mit diesem statement bekommst du nur ein game!

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
hm ich verstehs nicht :D aber ich versuchs mal einfach auf meinen fall umzusetzen.
danke erstmal für deine zeit!

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
Zitat von Umlüx
ich hab heut echt denkprobleme. ok nochmal von vorne. sagen wir, die tabellen sehen so aus.

Code:
Name    Game
Harald  2
Paul    3
Hugo    1
Harald  4

Game  Name  DLC
1     GTA
2     FC4
3     SC2
4     D3
4     D3    ROS

wenn ich wissen will was harald spielt und ich joine über Game, bekomm ich 2 results richtig? ich will aber nur den aktuellsten haben. in dem fall den mit dem ROS addon.
in dem fall bekommst du zwei weil harald 2x in Table A ist, die subquery über Table B wird dir immer nur einen zurückgeben. aber den gleichen Eintrag / Player in Table A müsstest wieder anders lösen

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
das würde mir eh so passen. ich will ihn nur nicht 3x sehen.

edith kommt leider immer noch nicht zurecht :(

was ich momentan habe:
Code: SQL
SELECT DISTINCT mis.Auftragsnummer, mis.Ticketnummer1, RTRIM(af_pnr.pnr)
FROM [IATA_AIR_FILES].[dbo].[mis]
JOIN [IATA_AIR_FILES].[dbo].[af_pnr]
	ON SUBSTRING(mis.Ticketnummer1,4,10) = 
		(SELECT TOP 1 ticket_number
		 FROM [IATA_AIR_FILES].[dbo].[af_pnr]
		 WHERE af_pnr.ticket_number = SUBSTRING(mis.Ticketnummer1,4,10)
		 ORDER BY af_pnr.pnr)
WHERE mis.Kundennummer = 76580 
  AND mis.Rechnungsdruckdatum like '201412%'
  AND mis.Auftragsunterposition = 0
  AND mis.Ticketnummer1 <> ''
  AND mis.Tickettype <> ''
  AND mis.Airline <> ''
ORDER BY mis.Auftragsnummer

ich bekomm zwar keine fehlermeldung, aber ... jo. nach 2 min hab ich die ausführung mal abgebrochen.

mis ist meine ausgangstabelle. dort kann ich die ersten filter ansetzen.
pnr aus der tabelle af_pnr ist das, was ich haben will.
joinen kann ich sie über die ticketnummer. mit substring, da wie gesagt das format nicht ganz gleich ist.
und da es mehrere zeilen mit unterschiedlichen pnr einträgen, aber der gleichen ticketnummer gibt, will ich das auf die aktuellste pnr filtern.
Bearbeitet von Umlüx am 25.02.2015, 14:25

Punisher

Bukanier
Avatar
Registered: Sep 2002
Location: Disneyland
Posts: 1867
Bei mir hat TOP 1 in mysql nicht funktioniert, habs dann in der subquery durch LIMIT 1 ersetzt

Umlüx

Huge Metal Fan
Avatar
Registered: Jun 2001
Location: Kärnten
Posts: 8962
limit gibts im MSSQL nicht.

die subquery alleine funktioniert. ersetz ich diese im ganzen query durch eine statische ticketnummer, bekomm ich die komplette tabelle af_pnr zurück

userohnenamen

leider kein name
Avatar
Registered: Feb 2004
Location: -
Posts: 15857
und ein einfaches TOP 1 wird wohl wegen des joins nicht so funktionieren wie gewünscht oder?

XeroXs

doh
Avatar
Registered: Nov 2000
Location: Lieboch
Posts: 10331
Was dem MySQL ein Limit ist dem MSSQL ein TOP ;)
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz