Mysql query get results if fields aren't equal - mysql

I have a query like this:
select a.*, ag.Winstpercentage from Artikels a
inner join Artikelgroep ag on a.`Artgroep`=ag.Groepcode
where a.`Manuf_nr` in (some array)
In this query I have price field. I need to compare Manuf_nr for all these fields, and if it's same I need to check that price fields are not equal for rows who have same Manuf_nr. Anyone knows how to do this?
UPDATE:
field price is in Artikels table, so I select it under a.*
I changed my query so it looks like this
SELECT *
FROM `Artikels`
inner join (select * from Artikels) as totals
on Artikels.`Manuf_nr` = totals.`Manuf_nr` and
Artikels.`Vprijsexcl`!= totals.`Vprijsexcl`
where Artikels.`Manuf_nr` in
(select Manuf_nr from Artikels
group by Manuf_nr having count(*) >1)
but it takes too long. Anyone knows how to speed it up?
UPDATE: field price is field Vprijsexcl
This is what I have:
my table
And I need to get all data where Manuf_nr is equal and Vprijsexcl are not equal.

Try:
SELECT *
FROM `Artikels`
inner join Artikels as totals
on Artikels.`Manuf_nr` = totals.`Manuf_nr` and
Artikels.`Vprijsexcl`!= totals.`Vprijsexcl`
- the where ... in (subquery) clause is redundant, because the main query can only return results from manufacturers that have more than one row in the Artikels table.
UPDATED: To see only the differing prices for the same manufacturer, try:
SELECT `Manuf_nr`, group_concat(distinct `Vprijsexcl`) prices
FROM `Artikels`
GROUP BY `Manuf_nr`
HAVING count(distinct `Vprijsexcl`) > 1

What about
SELECT Manuf_nr, Vprijsexcl, COUNT (*)
FROM Artikels
GROUP BY Manuf_nr, Vprijsexcl
HAVING COUNT (*) > 1
which lists the Manuf_nr, Vprijsexcl combinations that are not unique.
EDIT:
To get all information about the products which have a distinct Vprijsexcl for their Manuf_nr:
SELECT Artikels.*
FROM Artikels
INNER JOIN (SELECT Manuf_nr, Vprijsexcl, COUNT (*)
FROM Artikels
GROUP BY Manuf_nr, Vprijsexcl
HAVING COUNT (*) = 1) AS A
USING (Manuf_nr, Vprijsexcl)

Related

Apparently my Subquery returns more than 1 row

So I want to find all items from the parts table for which the price is greater than or equal to the average price of the respective product line.
And I tried it wirh subquerys and Group by but my Subquery returns more than one row. Any Help?
select * from parts
where price >= (select distinct avg(price)
from parts group by productLine)
You have to create a connection between the parts table and the average prices query, because as you have your subquery now, it returns the average price for all productlines, which you most probably you have more than one ... And also the DISTINCT doesn't help here, unless all of your productlines have the extact same AVG(price) -- which is quite unlikely.
With newer versions of mysql you can use a common table expression
with prices(avgprice, productline) as (
select avg(price), productline
from parts
group by productline)
select pa.*
from parts pa inner join prices pr on pa.productline = pr.productline
where pa.price >= pr.avgprice
If you are on a older version of mysql, which doesn't support CTE, you can also join on the result of a subquery
select pa.*
from parts pa inner join (
select avg(price) as avgprice, productline
from parts
group by productline) pr on pa.productline = pr.productline
where pa.price >= pr.avgprice
or you can just limit your subquery on the respective productline
select *
from parts p
where price >= (
select avg(price)
from parts pa
where pa.productline = p.productline)

Need MYSQL uquery solution

I have the folowing tree tables one is the stock_items with all the items in it. The stock_in has the stock movements in to the stock and stock_out has the out movements:
and I want to get such a query result:
could some one help me to make this query?
You want to select the stock items and join the in totals and out totals. Aggregate to get the totals. Outer join to get items with and without transactions. Use COALESCE to replace nulls with zeros.
select
s.barcode, s.item_name,
coalesce(si.total, 0) as amount_in,
coalesce(so.total, 0) as amount_out,
coalesce(si.total, 0) - coalesce(so.total, 0) as balance,
s.unit
from stock_items s
left join
(
select barcode, sum(amount) as total
from stock_in
group by barcode
) si on si.barcode = s.barcode
left join
(
select barcode, sum(amount) as total
from stock_out
group by barcode
) so on so.barcode = s.barcode
order by s.barcode;
You can join tables using the barcode column?
select * from stock_items
join stock_in on stock_items.barcode = stock_in.barcode
join stock_out on stock_items.barcode = stock_out.barcode
Just replace the * with a list of desired column names
Unleash the power of subqueries and then use subtraction to compute the total stock level.
Basically the strategy here is to:
Run one query to sum up the total stock in
Run another query to sum up the total stock out
Run a final query subtracting the summed values.
select *, (stock_in - stock_out) as total from (select
product_id pid,
product_name,
product_unit,
(select sum(stock_in) from stock_in where product_id=pid) as stock_in,
(select sum(stock_out) from stock_out where product_id=pid) as stock_out
from products) summed
SQL fiddle here: https://www.db-fiddle.com/f/v95qsALSfnm66HoQb6PqJ6/0

mysql select count union

I have something like this:
(SELECT COUNT(*) AS total FROM `transactions` WHERE
`asset`='u_{$user_id}' GROUP BY id)
UNION DISTINCT
(SELECT COUNT(*) AS total FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}'
GROUP BY tr.id)
It gives 1
Now works like this:
SELECT
(SELECT COUNT(*) FROM `transactions`
WHERE `asset`='u_{$user_id}')
+
(SELECT COUNT(*) FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}')
It gives 6
But i need to get 5.., sow how to make a right query?
Sure, i can do this by php, but..HOW by sql..?
Really "and" and "or" conditions does not matter, they works correctly, the problem is in counting UNION`ed query. The second query correctly counts summ (1+5), but values ​​intersect queries. The first one gives result of just first subquery. So, i need to unique results before count...
In php, it should look like that: i get transactions id list by inner join with payments, than construct a long query in a loop, to get something like SELECT COUNT(*) FROM transactions WHERE (*what i have now* OR id=$id_1 OR id=$id_2 OR id=$id_3 etc..)
UPD: cutted
RESOLVED!=)
SELECT COUNT(*) FROM(
SELECT tr.* FROM transactions tr
WHERE tr.asset='u_{$user_id}' OR (tr.liability='g' AND tr.l_info='{$user_name}')
UNION SELECT tr.* FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}' AND pa.status='100')
AS total
AS total is importantly!
I gone through your question, and i think you want to fetch the maximum from the union clause, well i am not aware of the mySql, so i have solved your question in MS-SQL.
Logic:- I have used CTE, and afterwards performed UNION operation and then i have selected MAXIMUM from the two.
WITH COUNTT AS (SELECT 1 AS TEST
UNION
SELECT 5 AS TEST)
SELECT MAX(TEST) FROM COUNTT
And, in place of hardcoded "1" and "5", you can use your count query, i think it is what you are looking for. And, please mark it as an answer.

Subquery returns more than 1 row

im geting this error when trying to do 2 counts inside of my query
first ill show you the query:
$sql = mysql_query("select c.id, c.number, d.name,
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount,
(select count(*) from `parts` where `id_container`=c.id) as partcount
from `containers` as c
left join `destinations` as d on (d.id = c.id_destination)
order by c.number asc") or die(mysql_error());
now the parts table has 2 fields that i need to use in the count:
id_car
id_container
id_car = the ID of the car the part is for
id_container = the ID of the container the part is in
for packcount all i want is a count of the total cars per container
for partcount all i want it a count of the total parts per container
It's because of GROUP BY You're using
Try something like
(select count(distinct id_car) from `parts` where `id_container`=c.id)
in You're subquery (can't check right now)
EDIT
PFY - I think UNIQUE is for indexes
Your grouping in your first sub-query is causing multiple rows to be returned, you will probably need to run separate queries to get the results you are looking for.
This subquery may return more than one row.
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount, ...
so, i'd suggest to try something of the following:
(select count(DISTINCT `id_car`) from `parts` where `id_container`=c.id) as packcount, ...
see: COUNT(DISTINCT) on dev.mysql.com
and: QA on stackoverflow

Counting rows in a Query containing Join

I have a query that goes like this:
SELECT Product.local_price*Rate.exchange_rate AS 'US_price' FROM Product
INNER JOIN Rate ON Rate.currency = Product.currency
WHERE Product.type='TV'
HAVING US_price BETWEEN 500 AND 600;
How do I do a count on the number of TV sets that satisfy this query?
Table structure
Product Table: ID, type, local_price
Rate Table: currency, exchange_rate
Replace the HAVING US_price with AND Product.local_price * Rate.exchange_rate and just do a COUNT(Product.ID) in the SELECT clause:
SELECT COUNT(Product.ID)
FROM Product
INNER JOIN Rate ON Rate.currency = Product.currency
WHERE Product.type='TV'
AND Product.local_price * Rate.exchange_rate BETWEEN 500 AND 600;
You would want to use a HAVING if you wanted criteria on aggregated data, like this:
SELECT p.type, AVG(p.local_price)
FROM Product p
GROUP BY p.type
HAVING AVG(p.local_price) > 50
There's no need to use a HAVING clause here; its special semantics are only relevant when you have a GROUP BY clause. So, we can simply replace US_price in the HAVING clause with the expression that generates it, and move it into the WHERE clause; and then, use SELECT COUNT(*):
SELECT COUNT(*)
FROM Product
JOIN Rate
ON Rate.currency = Product.currency
WHERE Product.type = 'TV'
AND Product.US_price * Rate.exchange_rate BETWEEN 500 AND 600
;
Also, as a general rule — not needed in this case — you can always (or almost always?) wrap your entire query in SELECT COUNT(*) FROM (...) t to get the total number of rows it returns.