Sorry for the long title.
I have a statement which needs to grab all the columns from one row from BinConfig:
SELECT *
FROM BinConfig WITH(NOLOCK)
WHERE IssuerKey = #IssuerKey
But I also need to grab a single column from one row from CardRangeGroup also based on that IssuerKey column.
What I've tried:
SELECT
BinConfig.*, CardRangeGroup.Name
FROM
BinConfig
JOIN
CardRangeGroup WITH(NOLOCK)
WHERE
#IssuerKey = BinConfig.IssuerKey
AND #IssuerKey = CardRangeGroup.IssuerKey
Which gives me a syntax error near WHERE. I've tried to find resources online, but everywhere I look I can't find anything explaining how to select rows based on a passed in variable. Any help?
You need to specify how the tables should be joined. Try this:
SELECT BinConfig.*, CardRangeGroup.Name
FROM BinConfig
JOIN CardRangeGroup ON BinConfig.IssuerKey = CardRangeGroup.IssuerKey
WHERE #IssuerKey = CardRangeGroup.IssuerKey
The with(nolock) might not be needed (or a good idea) so I removed it.
try this , you don't need to use where
SELECT BinConfig.*, CardRangeGroup.Name FROM BinConfig JOIN
CardRangeGroup
ON CardRangeGroup.IssuerKey = BinConfig.IssuerKey AND #IssuerKey = CardRangeGroup.IssuerKey
I have those two tables (Members and Now) I just need to make sure that no one in Members is actually in Now. Both tables have different structures but can be joined on firsname, lastname and postalcode.
So I tried this (in access)
SELECT Members.Prenom, Members.Nom, Members.Adresse, Members.[Adresse 2], Members.ville, Members.Province, Members.CodePostal
FROM Members
Left JOIN now ON (members.prenom = now.firstname AND members.nom = now.lastname
AND members.codepostal = now.postcode) WHERE now.id IS NULL
And it gives me a wonderful error message
invalid use of '.' ' ' or '()'. in query expression
May someone enlighten me on what I did wrong?
Pretty sure you cannot use 'now' as a table name, there are certain reserved words that MS Access need (in this case for function Now(), I guess the error message is telling you have missed the parentesis' ()). You could try encasing it in square brackets but I would strongly recommend changing your table name. A useful format I use is to prefix objects such as tblTableName, qryQueryName, rptReportName, frmFormName etc but whatever works for you.
SELECT Members.Prenom, Members.Nom, Members.Adresse, Members.[Adresse 2],
Members.ville, Members.Province, Members.CodePostal
FROM Members
Left JOIN [now] a ON (members.prenom = a.firstname AND members.nom = a.lastname
AND members.codepostal = a.postcode) WHERE a.id IS NULL
I have the following query:
DECLARE #AccString varchar(max)
SET #AccString=''
SELECT #Acctring=#AccString + description + ' [ ] '
FROM tl_sb_accessoryInventory ai
JOIN tl_sb_accessory a on a.accessoryID = ai.accessoryID
WHERE userID=6
SELECT userID, serviceTag, model, #AccString AS ACCESSORIES FROM tl_sb_oldLaptop ol
JOIN tl_sb_laptopType lt ON ol.laptopTypeID = lt.laptopTypeID
WHERE userID=6
which outputs this:
What I want to be able to do is run this for every userID in a table tl_sb_user.
The statement to get the userIDs is:
Select userID from tl_sb_user
How can I get this to output a row as above for each user?
You are trying to do a string concatenation subquery. In SQL Server, you need to do the string concatenation using a correlated subquery with for xml path. Arcane, but it generally works.
The results is something like this:
SELECT userID, serviceTag, model, #AccString AS ACCESSORIES,
stuff((select ' [ ] ' + description
from tl_sb_accessoryInventory ai join
tl_sb_accessory a
on a.accessoryID = ai.accessoryID
where a.userId = ol.UserId
for xml path ('')
), 1, 11, '') as accessories
FROM tl_sb_oldLaptop ol JOIN
tl_sb_laptopType lt
ON ol.laptopTypeID = lt.laptopTypeID;
You don't have table aliases identifying where the columns come from, so I am just guessing that a.userId = ol.UserId references the right tables.
Also, this substitutes certain characters with html forms. Notably '<' and '>' turn into things like '<' and '>'. When I encounter this problem, I use replace() to replace the values.
Simply leave out the WHERE clause.
Given a table of "events" where each event may be associated with zero or more "speakers" and zero or more "terms", those records associated with the events through join tables, I need to produce a table of all events with a column in each row which represents the list of "speaker_names" and "term_names" associated with each event.
However, when I run my query, I have duplication in the speaker_names and term_names values, since the join tables produce a row per association for each of the speakers and terms of the events:
1|Soccer|Bobby|Ball
2|Baseball|Bobby - Bobby - Bobby|Ball - Bat - Helmets
3|Football|Bobby - Jane - Bobby - Jane|Ball - Ball - Helmets - Helmets
The group_concat aggregate function has the ability to use 'distinct', which removes the duplication, though sadly it does not support that alongside the custom separator, which I really need. I am left with these results:
1|Soccer|Bobby|Ball
2|Baseball|Bobby|Ball,Bat,Helmets
3|Football|Bobby,Jane|Ball,Helmets
My question is this: Is there a way I can form the query or change the data structures in order to get my desired results?
Keep in mind this is a sqlite3 query I need, and I cannot add custom C aggregate functions, as this is for an Android deployment.
I have created a gist which makes it easy for you to test a possible solution: https://gist.github.com/4072840
Look up the speaker/term names independently from each other:
SELECT _id,
name,
(SELECT GROUP_CONCAT(name, ';')
FROM events_speakers
JOIN speakers
ON events_speakers.speaker_id = speakers._id
WHERE events_speakers.event_id = events._id
) AS speaker_names,
(SELECT GROUP_CONCAT(name, ';')
FROM events_terms
JOIN terms
ON events_terms.term_id = terms._id
WHERE events_terms.event_id = events._id
) AS term_names
FROM events
I ran accross this problem as well, but came up with a method that I found a bit easier to comprehend. Since SQLite reports SQLite3::SQLException: DISTINCT aggregates must have exactly one argument, the problem seems not so much related to the GROUP_CONCAT method, but with using DISTINCT within GROUP_CONCAT...
When you encapsulate the DISTINCT 'subquery' within a REPLACE method that actually does nothing you can have the relative simplicity of nawfal's suggestion without the drawback of only being able to concat comma-less strings properly.
SELECT events._id, events.name,
(group_concat(replace(distinct speakers.name),'',''), ' - ') AS speaker_names,
(group_concat(replace(distinct speakers.name),'',''), ' - ') AS term_names
FROM events
LEFT JOIN
(SELECT et.event_id, ts.name
FROM terms ts
JOIN events_terms et ON ts._id = et.term_id
) terms ON events._id = terms.event_id
LEFT JOIN
(SELECT sp._id, es.event_id, sp.name
FROM speakers sp
JOIN events_speakers es ON sp._id = es.speaker_id
) speakers ON events._id = speakers.event_id
GROUP BY events._id;
But actually I would consider this a SQLite bug / inconsistency, or am I missing something?
That's strange that SQLite doesnt support that!.
At the risk of being down voted, only if it helps:
You can avail Replace(X, Y, Z). But you have to be sure you wont have valid , values in your columns..
SELECT events._id, events.name,
REPLACE(group_concat(distinct speakers.name), ',', ' - ') AS speaker_names,
REPLACE(group_concat(distinct terms.name), ',', ' - ') AS term_names
FROM events
LEFT JOIN
(SELECT et.event_id, ts.name
FROM terms ts
JOIN events_terms et ON ts._id = et.term_id
) terms ON events._id = terms.event_id
LEFT JOIN
(SELECT sp._id, es.event_id, sp.name
FROM speakers sp
JOIN events_speakers es ON sp._id = es.speaker_id
) speakers ON events._id = speakers.event_id
GROUP BY events._id;
The problem arises only with the group_concat(X,Y) expression, not with the group_concat(X) expression.
group_concat(distinct X) works well.
So, if the ',' is good for you, there is no problem, but if you want a ';' instead of ',' (and you are sure no ',' is in your original text) you can do:
replace(group_concat(distinct X), ',', ';')
Just to put a proper workaround (murb's answer is strangely parenthesized).
problem:
group_concat(distinct column_name, 'custom_separator') takes custom_separator as a part of distinct.
solution:
We need some no-op to let SQLite know that distinct finished (to wrap distinct and it's arguments).
No-op can be replace with empty string as a second parameter (documentation to replace).
group_concat(replace(distinct column_name, '', ''), 'custom_separator')
edit:
just found that it does not work :-( - can be called but distinct is not working anymore
There is a special case that does not work in sqlite : group_concat(DISTINCT X, Y)
Whereas in SQL you can use group_concat(DISTINCT X SEPARATOR Y) in sqlite you can't
This example : Select group_concat(DISTINCT column1, '|') from example_table group by column2;
gives the result : DISTINCT aggregates must have exactly one argument At line 1:
The solution :
select rtrim(replace(group_concat(DISTINCT column1||'#!'), '#!,', '|'),'#!') from example_table
Morning All,
Im not to sure how i need to solve my following query... I have the following query which pulls back the desired records in SQL server...
SELECT agenda.AgendaItemNumber,Agenda.AgendaName, AgendaType.AgendaTypeDescription, userdetails.fullName
FROM Agenda
JOIN AgendaType ON AgendaType.AgendaTypeID=Agenda.AgendaTypeID
JOIN UserDetails ON Agenda.AgendaID = Userdetails.AgendaID
WHERE agenda.AgendaTypeID = '2'
AND AgendaItemNumber = AgendaItemNumber
AND AgendaName = AgendaName
AND AgendaTypeDescription = AgendaTypeDescription
AND AgendaItemNumber >= '3'
The above query works but i need to enhance this slightly. It pulls back the following results, which essentially are duplicate records except for the 'fullname' column...
What i would like to do is be able to add some extra code to this query so that when i run the query i am able to display one record for each 'AgendaItemNumber' and for it to concat both of the fullnames for this record. However i have additional AgendaItemsNumbers in this table that only have 1 x user fullname assigned to them. its just these few records within the image file i need to do something clever with.
Maybe there is a better way to complete this task?
Many thanks in advance. Any queries please dont hesitate to ask.
Regards
Betty
SELECT agenda.AgendaItemNumber,
Agenda.AgendaName,
AgendaType.AgendaTypeDescription,
STUFF(( SELECT ';' + FullName
FROM UserDetails
WHERE UserDetails.AgendaID = Agenda.AgendaID
FOR XML PATH('')
), 1, 1, '') AS fullName
FROM Agenda
INNER JOIN AgendaType
ON AgendaType.AgendaTypeID=Agenda.AgendaTypeID
INNER JOIN UserDetails
ON Agenda.AgendaID = Userdetails.AgendaID
WHERE agenda.AgendaTypeID = '2'
AND AgendaItemNumber = AgendaItemNumber
AND AgendaName = AgendaName
AND AgendaTypeDescription = AgendaTypeDescription
AND AgendaItemNumber >= '3'
ADENDUM
The XML extension in SQL-Server allows you to concatenate multiple rows into a single row. The actual intention of the extension is so you can output as XML (obviously), but there are some nifty tricks that are byproducts of the extensions. In the above query, if there were a column name in the subquery (FullName) it would output as <FullName>Joe Bloggs1</FullName><FullName>Joe Bloggs2</FullName>, because there is no column name it simply concatenates the rows (not forming proper XML). The PATH part allows you to specify an additional node, for example if you use PATH('Name') in the above you would get <Name>;Joe Bloggs</Name><Name>;Joe Bloggs2</Name> If you combine Path with a column name you would get Joe Bloggs.
Finally the STUFF just removes the semicolon at the start of the list.