How to get in MySQL defined names into php? - php

If I have a mysql query like
(SELECT COUNT(*) FROM data AS amount)
UNION
(SELECT COUNT(*) FROM data WHERE some < 50 AS something)
and then create an array with php like this $row = mysqli_fetch_array($sql, MYSQLI_ASSOC);.
How can I now address each of the AS names. This does not work: echo $row["amount"];. The second question I have is why can't I use AS something when having a WHERE clause?

Try this:
(
SELECT
'amount1' as za_name,
COUNT(*) as za_count
FROM
data
)
UNION
(
SELECT
'amount2' as za_name,
COUNT(*) as za_count
FROM
data
WHERE some < 50
)
Then you can differentiate by $row[za_name] and get the amount $row[za_count]
For the second question : you can use it if you make a temp table :
SELECT
tmp.za_name,
tmp.za_count
FROM (
SELECT
'amount2' as za_name,
COUNT(*) as za_count
FROM
data
WHERE some < 50
) as tmp

In a UNION the row names/aliases for the entire query are whatever they are in the first query.
So if you have
SELECT field1 AS A
UNION
SELECT field2 AS B
Your final result will only have an A field, which will have both field1 and field2.
In your query, you want to alias the COUNT(*), not the table.
(SELECT COUNT(*) AS amount FROM data)
UNION
(SELECT COUNT(*) FROM data WHERE some < 50)
Nor $row['amount'] will be all of the COUNT(*) rows from the entire query.

in your query
(SELECT COUNT(*) FROM data AS amount) UNION (SELECT COUNT(*) FROM data WHERE some < 50 AS something)
You are aliasing the table data to the name amount rather than the sub-query

You have to edit the query this way (aliases on the columns, too)
(SELECT COUNT(*) as amount FROM data)
UNION
(SELECT COUNT(*) as amount FROM data WHERE some < 50 AS something)
This way You are able to address $result['amount'] as a result from the fetch assoc method.

Related

How we can get the data from the table by limiting the number of identical columns MySql

Yesterday I tried to retrieve data from my db table using 'user_id' as a criterion to limit the amount of data per user.
I tried to get data from table https://prnt.sc/p53zhp in format like this https://prnt.sc/p541wk and limit the number of output records for user_id where limit will be 2 (count(user_id) <= 2), but i don't understand how to do that. What kind of sql request can i use to get this data?
Assuming that your RDBMS, here is a solution yo select only the top 2 records per user. You can use ROW_NUMBER() in a subquery to rank records by id within groups of records having the same user_id, and the filter out unerelevant records in the outer query, like:
SELECT *
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY id)
FROM mytable
) x WHERE rn <= 2
On earlier versions of MySQL, you could use self-LEFT JOIN the table and use GROUP BY and HAVING COUNT(...) < 2 to limit the results to first two records per group:
SELECT
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
FROM mytable t
LEFT JOIN mytable t1 ON t1.user_id = t.user_id AND t1.id > t.id
GROUP BY
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
HAVING COUNT(t1.id) < 2
I don't understand if your problem is a Transact-SQL or your code.
In SQL you can limit record with "LIMIT": https://www.w3schools.com/sql/sql_top.asp
In code, you can use a condition IF.

Group Concat the max id in the query

How can i group_concat the selected max id in the query.
example:
select group_concat(max(id) SEPARATOR ',') from attempts group by user, attempt having count(*) > 1;
im having an error code
1111: invalid use of group function
One option is to use a subquery:
SELECT GROUP_CONCAT(id)
FROM
(
SELECT MAX(id) AS id
FROM attempts
GROUP BY user
) t;
The subquery finds all max id values for users in your table. Then, we roll them up into a CSV string. Note that if you wanted only distinct id values then you could have done:
SELECT GROUP_CONCAT(DISTINCT id)

Find duplicate value accross multiple column within same row in Mysql

Please help find duplicate entries in multiple columns of same row in MySQL:
If you want to find the records that have duplicates in columns you can use this query:
SELECT T1.* FROM tbl T1
JOIN
(SELECT id
FROM (
SELECT id, sample1 AS n from tbl
UNION ALL
SELECT id, sample2 AS n from tbl
UNION ALL
SELECT id, sample3 AS n from tbl
) AS X
GROUP BY id, n
HAVING COUNT(*) > 1
) T2
ON T1.id = T2.id;
You can also test it Here
I am not sure with MySql,
But in PHP below example will use.
Example
$query = "select * from table_name";
$result = mysqli_query($query);
while ($row = mysqli_fetch_array($result)) {
if ($row['sample1'] == $row['sample2']) {
// This row duplicate
}
else {
// This row not duplicate
}
}
SELECT Sample1, COUNT(*) C FROM tablename GROUP BY Sample1 HAVING C > 1;
Finding duplicate values in MySQL
MySQL select records for duplicates using multiple columns

MySQL return union select results separated in groups

I would like to know if is possible to return the results from UNION grouped by their alias.
For instance:
(SELECT * FROM table1) AS first
UNION
(SELECT * FROM table2) AS second
so that the result is:
first = contains all table1 rows
second = contains all table2 rows
Practically i want an associative array like this:
[]=>[
'first'=>[table1 results],
'second'=>[table2 results]
]
I tried it but doesn't work. Maybe i'm doing it bad.
Can this be done with a single query or i've to do 2 separated queries.
Thanks.
You cannot do this with union because it removes duplicates. You can with union all.
One way is:
SELECT t.*, 0 as which FROM table1 t
UNION ALL
SELECT t.*, 1 FROM table2 t
ORDER BY which;
If you don't want to see which in the output, use a subquery:
select . . .
from (select t.*, 0 as which from table1 t union all
select t.*, 1 as which from table1 t
) t
order by which;

Laravel query builder - Union All with Skip and Take

I need to get data from a table using this query:
(select columns
from tableX
join tableZ
on tableX.id1 = tableZ.other_id)
union all
(select columns
from tableX
join tableZ
on tableX.id2 = tableZ.other_id)
LIMIT num1, num2
Without the LIMIT, I get the correct result with my query builder that look like this (let $first be the first query of select and $second is the other select query):
$first->unionAll($second)->get();
When I try to put skip and/or take, the result is not the same as the first query above.
$first->unionAll($second)->take(num1)->skip(num2)->get();
The result query from the above builder (I got it from DB::getQueryLog()) is something like:
(select columns
from tableX
join tableZ
on tableX.id1 = tableZ.other_id LIMIT num1, num2)
union all
(select columns
from tableX
join tableZ
on tableX.id2 = tableZ.other_id)
which ofcourse yield incorrect result. Does anyone knows what is the work around to make the first query? Thanks!
You need to wrap $firstQuery in another query, like this:
$first->unionAll($second);
$rows = DB::table( DB::raw("({$first->toSql()}) as t") )
->mergeBindings($first->getQuery())
->take(num1)->skip(num2)
->get();
This will result in the following query:
select * from (FIRST_QUERY union all SECOND_QUERY) as t limit num1, num2
One Workaround is to use raw query using DB::select and DB::raw in below sample block...
$num1 = 100; // skip first 100 rows
$num2 = 2; // take only 2 rows
$qry_result = DB::select(DB::raw("select * from
(
(select columns from tableX join tableZ on tableX.id1 = tableZ.other_id)
union all
(select columns from tableX join tableZ on tableX.id2 = tableZ.other_id)
) Qry LIMIT :vskip , :vlimit ") , array('vskip'=>$num1,'vlimit'=>$num2)
);

Categories