Group Concat from a select statement - mysql

I am not sure if my method is possible, but i'm trying to do a group_concat on a select statement that concats 2 fields. I get the error: Subquery returns more than 1 row each time. Can anyone help me as to a solution, or better way around this.
select t.recnum, (select group_concat((select concat(b.origtests,'^', d.name) as testing
from order_origtests b
join profile c on c.code = b.origtests
join department d on d.recnum = c.dept
)))
FROM order_ t

You don't put SELECT inside GROUP_CONCAT. It should be
select t.recnum, (
select group_concat(concat(b.origtests,'^', d.name))
from order_origtests b
join profile c on c.code = b.origtests
join department d on d.recnum = c.dept
) AS testing
FROM order_ t
Note that your subquery isn't correlated to anything in t, so you'll get the same testing column for every recnum.

Related

How to return some predefined value when no row returned from big query with multiple column is selected

My query has multiple column being selected but now i want when no returned I want some dummy value to be returned.
For example in the following query:
SELECT a.abc, b.def, c.ghi
FROM comp a, damp b, champ c, omp d
WHERE a.id=b.id
and b.id=c.id
and c.id= d.id
ORDER BY a.abc desc
if there is no row returned I wanted to display atleast one column with some value, can somebody suggest me how can I achieve this.
I have already gone through some suggestion but none worked. Any help would be appreciated.
In oracle you could do something like this:
WITH mybigselect AS
(
SELECT a.abc, b.def, c.ghi
FROM comp a
JOIN damp b ON a.id = b.id
JOIN champ c ON b.id = c.id
JOIN omp d ON c.id = d.id
ORDER BY a.abc desc
)
SELECT * FROM mybigselect
UNION ALL
SELECT 'Nothing found', NULL, NULL FROM mybigselect
WHERE NOT EXISTS (SELECT * FROM mybigselect)
Note 1: that both rows in the UNION ALL needs to return columns of the same datatype. You can't return a number in the first column of SELECT * FROM mybigselect and "nothing found" in the query after UNION ALL
Note 2: rewrote the query using ANSI-JOIN style syntax.
I would recommend:
WITH cte as (
SELECT a.abc, b.def, c.ghi
FROM comp do JOIN
damp d
ON d.id = co.id JOIN
champ c
ON ch.id = d.id
omp o
ON o.id = ch.id
)
SELECT *
FROM cte
UNION ALL
SELECT 'Some value', NULL, NLL
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM cte)
ORDER BY abc DESC;
Notes:
The value has to be compatible with the type of the column. So, if abc is not a string, then 'Some value' is not appropriate. You haven't provided enough information to determine what value should be in which column.
The ORDER BY should be in the outermost query, not the CTE.
Never use comas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.
This version uses meaningful table aliases (table name abbreviations) rather than arbitrary letters.

SQL Complex update query filter distinct values only

I have 3 tables with following columns.
Table: A with column: newColumnTyp1, typ2
Table: B with column: typ2, tableC_id_fk
Table: C with column: id, typ1
I wanted to update values in A.newColumnTyp1 from C.typ1 by following logic:
if A.typ2=B.typ2 and B.tableC_id_fk=C.id
the values must be distinct, if any of the conditions above gives multiple results then should be ignored. For example A.typ2=B.typ2 may give multiple result in that case it should be ignored.
edit:
the values must be distinct, if any of the conditions above gives multiple results then take only one value and ignore rest. For example A.typ2=B.typ2 may give multiple result in that case just take any one value and ignore rest because all the results from A.typ2=B.typ2 will have same B.tableC_id_fk.
I have tried:
SELECT DISTINCT C.typ1, B.typ2
FROM C
LEFT JOIN B ON C.id = B.tableC_id_fk
LEFT JOIN A ON B.typ2= A.typ2
it gives me a result of table with two columns typ1,typ2
My logic was, I will then filter this new table and compare the type2 value with A.typ2 and update A.newColumnTyp1
I thought of something like this but was a failure:
update A set newColumnTyp1= (
SELECT C.typ1 from
SELECT DISTINCT C.typ1, B.typ2
FROM C
LEFT JOIN B ON C.id = B.tableC_id_fk
LEFT JOIN A ON B.typ2= A.type2
where A.typ2=B.typ2);
I am thinking of an updateable CTE and window functions:
with cte as (
select a.newColumnTyp1, c.typ1, count(*) over(partition by a.typ2) cnt
from a
inner join b on b.type2 = a.typ2
inner join c on c.id = b.tableC_id_fk
)
update cte
set newColumnTyp1 = typ1
where cnt > 1
Update: if the columns have the same name, then alias one of them:
with cte as (
select a.typ1, c.typ1 typ1c, count(*) over(partition by a.typ2) cnt
from a
inner join b on b.type2 = a.typ2
inner join c on c.id = b.tableC_id_fk
)
update cte
set typ1 = typ1c
where cnt > 1
I think I would approach this as:
update a
set newColumnTyp1 = bc.min_typ1
from (select b.typ2, min(c.typ1) as min_typ1, max(c.typ1) as max_typ1
from b join
c
on b.tableC_id_fk = c.id
group by b.type2
) bc
where bc.typ2 = a.typ2 and
bc.min_typ1 = bc.max_typ1;
The subquery determines whether typ1 is always the same. If so, it is used for updating.
I should note that you might want the most common value assigned, instead of requiring unanimity. If that is what you want, then you can ask another question.

concat() with select query?

I need to use a concat function which has an argument returned by select query like this
CONCAT(classification_version.NAME,' ',
(select x.NAME,min(DATEDIFF(e.SEND_DATE, x.OPTENTION_DATE))
AS DT_DIFF
from classification_version x inner join classification_element y
on x.id_project=y.ID_PROJECT inner join email e
on x.id_project=e.ID_PROJECT_AMENDMENT
where
y.ID_PROJECT=project.id and y.ID_COMPANY=company.id
and e.SEND_DATE>x.OPTENTION_DATE group by e.id,e.SEND_DATE
order by e.SEND_DATE ASC)
This is only a part of a query that I have. I need to return min(datediff) because I need the corresponding name value only. But it throws an error that Operand should contain 1 column(s). I cannot use inner queries for the select statement as project.id and company.id will not be available to me then. IS there any way to solve this?
I modified your SQL check it once.
SELECT CONCAT(q1.NAME,' ',DT_DIFF) FROM
(SELECT x.NAME,MIN(DATEDIFF(e.SEND_DATE, x.OPTENTION_DATE))
AS DT_DIFF
FROM classification_version x INNER JOIN classification_element y
ON x.id_project=y.ID_PROJECT INNER JOIN email e
ON x.id_project=e.ID_PROJECT_AMENDMENT
WHERE
y.ID_PROJECT=project.id AND y.ID_COMPANY=company.id
AND e.SEND_DATE>x.OPTENTION_DATE GROUP BY e.id,e.SEND_DATE
ORDER BY e.SEND_DATE ASC) AS q1
Thank you.

MAX() Function not working as expected

I've created sqlfiddle to try and get my head around this http://sqlfiddle.com/#!2/21e72/1
In the query, I have put a max() on the compiled_date column but the recommendation column is still coming through incorrect - I'm assuming that a select statement will need to be inserted on line 3 somehow?
I've tried the examples provided by the commenters below but I think I just need to understand this from a basic query to begin with.
As others have pointed out, the issue is that some of the select columns are neither aggregated nor used in the group by clause. Most DBMSs won't allow this at all, but MySQL is a little relaxed on some of the standards...
So, you need to first find the max(compiled_date) for each case, then find the recommendation that goes with it.
select r.case_number, r.compiled_date, r.recommendation
from reporting r
join (
SELECT case_number, max(compiled_date) as lastDate
from reporting
group by case_number
) s on r.case_number=s.case_number
and r.compiled_date=s.lastDate
Thank you for providing sqlFiddle. But only reporting data is given. we highly appreciate if you give us sample data of whole tables.
Anyway, Could you try this?
SELECT
`case`.number,
staff.staff_name AS ``case` owner`,
client.client_name,
`case`.address,
x.mx_date,
report.recommendation
FROM
`case` INNER JOIN (
SELECT case_number, MAX(compiled_date) as mx_date
FROM report
GROUP BY case_number
) x ON x.case_number = `case`.number
INNER JOIN report ON x.case_number = report.case_number AND report.compiled_date = x.mx_date
INNER JOIN client ON `case`.client_number = client.client_number
INNER JOIN staff ON `case`.staff_number = staff.staff_number
WHERE
`case`.active = 1
AND staff.staff_name = 'bob'
ORDER BY
`case`.number ASC;
Check below query:
SELECT c.number, s.staff_name AS `case owner`, cl.client_name,
c.address, MAX(r.compiled_date), r.recommendation
FROM case c
INNER JOIN (SELECT r.case_number, r.compiled_date, r.recommendation
FROM report r ORDER BY r.case_number, r.compiled_date DESC
) r ON r.case_number = c.number
INNER JOIN client cl ON c.client_number = cl.client_number
INNER JOIN staff s ON c.staff_number = s.staff_number
WHERE c.active = 1 AND s.staff_name = 'bob'
GROUP BY c.number
ORDER BY c.number ASC
SELECT
case.number,
staff.staff_name AS `case owner`,
client.client_name,
case.address,
(select MAX(compiled_date)from report where case_number=case.number),
report.recommendation
FROM
case
INNER JOIN report ON report.case_number = case.number
INNER JOIN client ON case.client_number = client.client_number
INNER JOIN staff ON case.staff_number = staff.staff_number
WHERE
case.active = 1 AND
staff.staff_name = 'bob'
GROUP BY
case.number
ORDER BY
case.number ASC
try this

mysql subquery returns more than 1 row

I have the following query :
(select xyz.* from
(select xt.image, p.*, pc.categoryid, c.category,
(select value from xcart_extra_field_values
where efv.productid=p.productid and efv.fieldid = 2) as Type,
(select value from xcart_extra_field_values
where efv.productid=p.productid and efv.fieldid = 1) as Zone
FROM xcart_products p
inner join xcart_products_categories pc
on p.productid=pc.productid
inner join xcart_categories c
on pc.categoryid=c.categoryid
inner join xcart_extra_field_values efv
on p.productid=efv.productid
inner join xcart_images_T xt
on p.productid=xt.id) xyz
where categoryid='1' and Type='2' and Zone='1'
group by productid)
But when I execute this query in phpmyadmin it displays a error messgae :
#1242 - Subquery returns more than 1 row
Whats wrong in the query.Please help. Thanks in advance.
I think (part of) the problem is that you are re-using an alias in a wrong location.
You should one use an alias once, and don't mix them for different instances of the same table.
(select xyz.* from
(select xt.image, p.*, pc.categoryid, c.category,
(select value from xcart_extra_field_values efv2
where efv2.productid=p.productid and efv2.fieldid = 2) as Type,
(select value from xcart_extra_field_values efv3
where efv3.productid=p.productid and efv3.fieldid = 1) as Zone
FROM xcart_products p
inner join xcart_products_categories pc
on p.productid=pc.productid
inner join xcart_categories c
on pc.categoryid=c.categoryid
inner join xcart_extra_field_values efv1
on p.productid=efv1.productid
inner join xcart_images_T xt
on p.productid=xt.id) xyz
where categoryid='1' and Type='2' and Zone='1'
group by productid)
So use a unique alias efvx for each xcart_extra_field_values table instance.
Execute each subquery manually in phpmyadmin and see which one is returning more than one row and you have your answer. Another option is to add a limit of 1 to each subquery to make sure only one row is returned. Of course it is better to look for the bug and solve it.