MySQL Query Displaying Multiple Comma Delimted Values from one Field Group Concat? - mysql

I have the following query that isn't returning the expected results.
I am trying to get all of the group names from a field, group_id, that potentially has multiple group_ids that are separated by commas (ex., 1,4,5,7,22). My original query returned only the first group listed in the list of groups_ids but did not return any group after the first comma. It returned just under 3,000 records.
To fix this, I tried using the group_concat function. It worked (no error), but it only returned one record when I was expecting close to 3,000.
I am not sure if I am using the function incorrectly or I am just missing code? If there is another function that would work better, I am all for it. Thanks in advance for your help!
My Query:
select `v`.`asset_id` AS `asset_id`,
`v`.`watched_on` AS `watched_on`,
`v`.`status` AS `Completed_Status`,
`va`.`asset_name` AS `asset_name`,
`u`.`fname` AS `fname`,
`u`.`lname` AS `lname`,
group_concat(distinct `g`.`name` separator ',') AS `group_name`
from (((`vm_video_history` `v`
join `vm_users` `u` on((`u`.`id` = `v`.`user_id`)))
left join `vm_groups` `g` on((`g`.`group_id` = `u`.`group_id`)))
left join `vm_assets` `va` on((`va`.`asset_id` = `v`.`asset_id`)))
order by `v`.`user_id`;

Related

SQL Join ON clause valid referencing on aliases

I am generating an SQL query and I need to get the data from a JSON stored on a field of my table. It goes something like this
SELECT creation.INSERT_DATE as applicationDateTime,
REPLACE(json_extract(creation.FACILITY_DATA, '$.loanType'), '"', '') AS loanType,
lookup_detail.DETAIL_DESCRIPTION AS financingType
FROM creation
LEFT JOIN lookup_detail ON lookup_detail.DETAIL_CODE = loanType
So basically I am trying to get put a connection with tables creation and lookup_detail through field FACILITY_DATA which has JSON data and alias of loanType to reference against DETAIL_CODE field. However, I get this error
code:"ER_BAD_FIELD_ERROR"
errno:1054
sqlMessage:"Unknown column 'loanType' in 'on clause'"
sqlState:"42S22"
Is there anything I could do to work on this? I tried to search what are the valid reference to ON clause of JOIN operation, but I only get the typical ways.
Either repeat the expression in the ON clause, or join with a subquery.
SELECT c.applicationDateTime, c.loanType, l.financingType
FROM (
SELECT INSERT_DATE as applicationDateTime,
REPLACE(json_extract(creation.FACILITY_DATA, '$.loanType'), '"', '') AS loanType
FROM creation
) AS c
JOIN lookup_detail AS l ON l.DETAIL_CODE = c.loanType
Also, you probably should be using JSON_UNQUOTE() rather than REPLACE(). Or you can use the ->> operator, which extracts and unquotes in one step.

SQL JOIN gives double results

My database and SQL:
http://sqlfiddle.com/#!9/ebddb/1/0
Problem:
It's returning duplicates, with the wrong data in the name-column, when there are less than 7 records in the notchtype-table
My Question:
Why does it return duplicates and how to prevent it?
Expected result:
This fiddle shows the expected result: http://sqlfiddle.com/#!9/22660/1
In this result the only thing more added than in my actual database and SQL are 2 records in the notchtype-table
So the id, notchid and number columns should be unique in the returned rows.
The screenshot in the answer of Piyush Gupta is showing the right expected result. The same query on SQL fiddle and locally on MariaDB version 10.1.9 are returning something different
Notes:
I found out that when there at least 7 records in the notchtype table, there are suddenly no duplicates anymore and the problem is 'solved'.
The null values should indeed be null.
The size-column is actually returning the right values, although the LEFT JOIN is more or less the same
The ID's in notches.notchdescr 'connects' with the ID's in notchtype.notchtypeid column and is returned as the name column in the fiddle
The ID's in notches.notchsize 'connects' with the ID's in notchsize.notchsizeid column and is returned as the size column in the fiddle
Not working:
INNER JOIN, don't know why
DISTINCT, because the name-columns have different values, so there not exact duplicates
GROUP BY, because it returns all the same values in the name-column
Update on answer/comments from Piyush Gupta
Query executed on MySQL 5.7:
SELECT
notches.id,
notches.notchid,
notches.number,
notches.xcoord,
notches.ycoord,
notches.mapid,
notches.location,
notches.date,
notches.price,
notches.invoiced,
notchsize.size AS notchsize,
notchtype.name AS notchdescr
FROM
notches
LEFT JOIN
notchtype ON
notches.notchdescr = notchtype.notchtypeid
LEFT JOIN
notchsize ON
notches.notchsize = notchsize.notchsizeid
WHERE
notches.del = 0
AND
notches.projectid = '2016032411364363055'
GROUP BY notches.id, notches.notchid, notches.number
ORDER BY notches.number ASC
Result:
SOLVED!
LEFT JOIN on VARCHAR = BIGINT field causes the strange returned values. See answer and comments of Piyush Gupta
You missed the GROUP BY in your query for Aggregate the data. so your query will be,
SELECT
notches.id,
notches.notchid,
notches.number,
notches.xcoord,
notches.ycoord,
notches.mapid,
notches.location,
notches.descr,
notches.date,
notches.price,
notches.invoiced,
notchtype.name AS notchdescr,
notchsize.size AS notchsize
FROM
notches
LEFT JOIN
notchtype ON
notches.notchdescr = notchtype.notchtypeid
LEFT JOIN
notchsize ON
notches.notchsize = notchsize.notchsizeid
WHERE
notches.del = 0
AND
notches.projectid = '2016032411364363055'
GROUP BY notches.id,
notches.notchid,
notches.number
ORDER BY notches.number ASC;
Output: ONLINE DEMO HERE
NOTE: I Imported your data structure locally and I'm getting same output which is your expectation but In SQLFiddle, notchtype.name AS notchdescr column is not executing in SQLFiddle that is showing only name column of notchtype table. So you can use above query and check locally in your database. I hope you will get require output.
Screenshot(Using MySQL Workbench)
Update 1: It was strange error. I reviewed database structure and found solution that was data type issue only. You were joining bigint and varchar data type so you need to correct data type. Here I'm changing data type bigint to varchar for notchsizeid in notchsize table and notchtypeid in notchtype table. Finally your Expected output is coming. You can SEE OUTPUT HERE.
You can do by using group by . But you need to tell your logic for this.
SELECT
notches.id,
notches.notchid,
notches.number,
notches.xcoord,
notches.ycoord,
notches.mapid,
notches.location,
notches.descr,
notches.date,
notches.price,
notches.invoiced,
notchtype.name AS notchdescr,
notchsize.size AS notchsize
FROM
notches
LEFT JOIN
notchtype ON
notches.notchdescr = notchtype.notchtypeid
LEFT JOIN
notchsize ON
notches.notchsize = notchsize.notchsizeid
WHERE
notches.del = 0
AND
notches.projectid = '2016032411364363055'
group by id
ORDER BY notches.number ASC

MYSQL GROUP_CONCAT and IN

I have a little query, it goes like this:
It's slightly more complex than it looks, the only issue is using the output of one subquery as the parameter for an IN clause to generate another. It works to some degree - but it only provides the results from the first id in the "IN" clause. Oddly, if I manually insert the record ids "00003,00004,00005" it does give the proper results.
What I am seeking to do is get second level many to many relationship - basically tour_stops have items, which in turn have images. I am trying to get all the images from all the items to be in a JSON string as 'item_images'. As stated, it runs quickly, but only returns the images from the first related item.
SELECT DISTINCT
tour_stops.record_id,
(SELECT
GROUP_CONCAT( item.record_id ) AS in_item_ids
FROM tour_stop_item
LEFT OUTER JOIN item
ON item.record_id = tour_stop_item.item_id
WHERE tour_stop_item.tour_stops_id = tour_stops.record_id
GROUP BY tour_stops.record_id
) AS rel_items,
(SELECT
CONCAT('[ ',
GROUP_CONCAT(
CONCAT('{ \"record_id\" : \"',record_id,'\",
\"photo_credit\" : \"',photo_credit,'\" }')
)
,' ]')
FROM images
WHERE
images.attached_to IN(rel_items) AND
images.attached_table = 'item'
ORDER BY img_order ASC) AS item_images
FROM tour_stops
WHERE
tour_stops.attached_to_tour = $record_id
ORDER BY tour_stops.stop_order ASC
Both of these below answers I tried, but it did not help. The second example (placing the entire first subquery inside he "IN" statement) not only produced the same results I am already getting, but also increased query time exponentially.
EDIT: I replaced my IN statement with
IN(SELECT item_id FROM tour_stop_item WHERE tour_stops_id = tour_stops.record_id)
and it works, but it brutally slow now. Assuming I have everything indexed correctly, is this the best way to do it?
using group_concat in PHPMYADMIN will show the result as [BLOB - 3B]
GROUP_CONCAT in IN Subquery
Any insights are appreciated. Thanks
I am surprised that you can use rel_items in the subquery.
You might try:
concat(',', images.attached_to, ',') like concat('%,', rel_items, ',%') and
This may or may not be faster. The original version was fast presumably because there are no matches.
Or, you can try to change your in clause. Sometimes, these are poorly optimized:
exists (select 1
from tour_stop_item
where tour_stops_id = tour_stops.record_id and images.attached_to = item_id
)
And then be sure you have an index on tour_stop_item(tour_stops_id, item_id).

My SQL JOIN query returning No results

SELECT 'nmc_cd.CDID','nmc_cd.CDTitle', 'nmc_cd.CDYear','nmc_cd.pubID','nmc_cd.catID','nmc_cd.CDPrice','nmc_category.catDesc'
From nmc_cd
JOIN nmc_category
ON 'nmc_cd.catID'='nmc_category.catID'
ORDER BY CDTitle
Ive been putting this query into mySQL to try and get a table with results from ncm_CD and nmc_category but it keeps retuning no value?? also if i use a right or left join it is returning the Column name (e.g. nmc_cd.CDJD)
Try removing the quotes so that you are referencing the column itself - with quotes, you are working with strings and not the columns.
SELECT nmc_cd.CDID, nmc_cd.CDTitle, nmc_cd.CDYear, nmc_cd.pubID, nmc_cd.catID, nmc_cd.CDPrice, nmc_category.catDesc
From nmc_cd
JOIN nmc_category
ON nmc_cd.catID = nmc_category.catID
ORDER BY CDTitle
Also, as #Randy mentions, make sure you actually have data that matches the criteria :)
I am not sure why you have single quotes around everything, a single quote is considered a static string value so it will not return the data from the columns:
SELECT nmc_cd.CDID,
nmc_cd.CDTitle,
nmc_cd.CDYear,
nmc_cd.pubID,
nmc_cd.catID,
nmc_cd.CDPrice,
nmc_category.catDesc
From nmc_cd
INNER JOIN nmc_category
ON nmc_cd.catID=nmc_category.catID
ORDER BY CDTitle
But with the INNER JOIN that you are using you have to be sure that you have values that match data in both tables, if you do not then no data will be returned. If you don't have data in both tables, then you will want to use either a LEFT JOIN or RIGHT JOIN:
SELECT nmc_cd.CDID,
nmc_cd.CDTitle,
nmc_cd.CDYear,
nmc_cd.pubID,
nmc_cd.catID,
nmc_cd.CDPrice,
nmc_category.catDesc
From nmc_cd
LEFT JOIN nmc_category
ON nmc_cd.catID=nmc_category.catID
ORDER BY CDTitle
MySQL uses backticks around columns and table names not single quotes, if you applied them then your query would look like this:
SELECT `nmc_cd`.`CDID`,
`nmc_cd`.`CDTitle`,
`nmc_cd`.`CDYear`,
`nmc_cd`.`pubID`,
`nmc_cd`.`catID`,
`nmc_cd`.`CDPrice`,
`nmc_category`.`catDesc`
From `nmc_cd`
JOIN `nmc_category`
ON `nmc_cd`.`catID`=`nmc_category`.`catID`
ORDER BY `CDTitle`

MySQL COUNT() causing empty array() return

MySQL Server Version: Server version: 4.1.14
MySQL client version: 3.23.49
Tables under discussion: ads_list and ads_cate.
Table Relationship: ads_cate has many ads_list.
Keyed by: ads_cate.id = ads_list.Category.
I am not sure what is going on here, but I am trying to use COUNT() in a simple agreggate query, and I get blank output.
Here is a simple example, this returns expected results:
$queryCats = "SELECT id, cateName FROM ads_cate ORDER BY cateName";
But if I modify it to add the COUNT() and the other query data I get no array return w/ print_r() (no results)?
$queryCats = "SELECT ads_cate.cateName, ads_list.COUNT(ads_cate.id),
FROM ads_cate INNER JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName ORDER BY cateName";
Ultimately, I am trying to get a count of ad_list items in each category.
Is there a MySQL version conflict on what I am trying to do here?
NOTE: I spent some time breaking this down, item by item and the COUNT() seems to cause the array() to disappear. And the the JOIN seemed to do the same thing... It does not help I am developing this on a Yahoo server with no access to the php or mysql error settings.
I think your COUNT syntax is wrong. It should be:
COUNT(ads_cate.id)
or
COUNT(ads_list.id)
depending on what you are counting.
Count is an aggregate. means ever return result set at least one
here you be try count ads_list.id not null but that wrong. how say Myke Count(ads_cate.id) or Count(ads_list.id) is better approach
you have inner join ads_cate.id = ads_list.category so Count(ads_cate.id) or COUNT(ads_list.id) is not necessary just count(*)
now if you dont want null add having
only match
SELECT ads_cate.cateName, COUNT(*),
FROM ads_cate INNER JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
having not count(*) is null
ORDER BY cateName
all
SELECT ads_cate.cateName, IFNULL(COUNT(*),0),
FROM ads_cate LEFT JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
ORDER BY cateName
Did you try:
$queryCats = "SELECT ads_cate.cateName, COUNT(ads_cate.id)
FROM ads_cate
JOIN ads_list ON ads_cate.id = ads_list.category
GROUP BY ads_cate.cateName";
I am guessing that you need the category to be in the list, in that case the query here should work. Try it without the ORDER BY first.
You were probably getting errors. Check your server logs.
Also, see what happens when you try this:
SELECT COUNT(*), category
FROM ads_list
GROUP BY category
Your array is empty or disappear because your query has errors:
there should be no comma before the FROM
the "ads_list." prefix before COUNT is incorrect
Please try running that query directly in MySQL and you'll see the errors. Or try echoing the output using mysql_error().
Now, some other points related to your query:
there is no need to do ORDER BY because GROUP BY by default sorts on the grouped column
you are doing a count on the wrong column that will always give you 1
Perhaps you are trying to retrieve the count of ads_list per ads_cate? This might be your query then:
SELECT `ads_cate`.`cateName`, COUNT(`ads_list`.`category`) `cnt_ads_list`
FROM `ads_cate`
INNER JOIN `ads_list` ON `ads_cate`.`id` = `ads_list`.`category`
GROUP BY `cateName`;
Hope it helps?