I have query like this :
SELECT * FROM (
SELECT * FROM (
SELECT 1 AS a,1 AS b
UNION
SELECT 2 AS a,1 AS b
UNION
SELECT 3 AS a,2 AS b
UNION
SELECT 3 AS a,1 AS b
) b ORDER BY b.b DESC
) c
It's show different result on different machine,
On Machine A :
A | B
--------
3 | 2
1 | 1
2 | 1
3 | 1
On Machine B :
A | B
--------
1 | 1
2 | 1
3 | 2
3 | 1
I'm expecting all machine will get result like machine A. How can it happen ? Is there any setting on mysql server to make all machine to get result like machine A ?
The inner ORDER BY is meaningless as you have written it, and only an ORDER BY on the outer query will be honored. In addition, I don't even see the point of the subquery, so just use this:
SELECT * FROM (
SELECT 1 AS a, 1 AS b
UNION
SELECT 2, 1
UNION
SELECT 3, 2
UNION
SELECT 3, 1
) t
ORDER BY b DESC;
SQL tables are modeled after unordered sets of records, and generally have no internal order. The inner ORDER BY you were doing does not "stick," and MySQL is free to return any order it wants in the outer query since you did not use ORDER BY there.
Related
I am looking for a way to populate values in row in mysql
for example if i execute query
select 1,2,3,4
it gives response
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
that is in row
is there a possible way to produce this data in column
like
1
2
3
4
With the introduction of Recursive with clause in MySQL version 8.0 or higher, We now have a row generator in MySQL -
WITH RECURSIVE cte_count (n)
AS (
SELECT 1
UNION ALL
SELECT n + 1
FROM cte_count
WHERE n < 100
)
SELECT n
FROM cte_count;
Before version 8.0 MySQL doesn't have any inbuilt row_generator functionality.
If you want values in a column, you can use:
select 1 as n union all
select 2 as n union all
select 3 as n union all
select 4 as n
This construct is often used in derived tables (or more recently in CTEs).
If you just need a set number of values, then an existing table (that is big enough) can be used:
select (#rn := #rn + 1) as n
from t cross join
(select #rn := 0) params
limit 4;
I have two tables :
Table:#a
id | name
10 | a
20 | b
30 | c
40 | d
50 | e
Table:#b
id | name
10 | a
30 | a
50 | a
I want all the #a table Id which are not present in #b
The following query works :
select * from #a as a
where not exists(select * from #b as b where a.id = b.id)
But I am not able to understand why the below query does not work
select * from #a as a
where exists(select * from #b as b where a.id <> b.id)
Why does where not exists expression does not give correct output
The first query does yield the right result : select all records from A where doesnt have appropriate match in B
But the second one is logically different.
Looking at :
;with A(id,name) as
(
select 10,'a' UNION ALL
select 20,'b' UNION ALL
select 30,'c' UNION ALL
select 40,'d' UNION ALL
select 50,'e'
) ,B(id,name) as
(
select 10,'a' UNION ALL
select 30,'a' UNION ALL
select 50,'a'
)
select * from a as a
where exists(select * from b as b where a.id <> b.id)
For each record from a, show that record if exists records from b with non-matched id.
So for 10,a (in a) there ARE(!) records from B where id is not 10 , hence it does YIELDS 10,a (from a)!
Now - do you see the problem ?
I am searching an addresses table for duplicates, using SOUNDEX to find the duplicates. This works fine, and it requires all 5 soundex columns to match in order to group
However, I want to GROUP where ANY 3 of my 5 SOUNDEX columns match.
Here is my current query:
SELECT `Address`.`id`,
SOUNDEX(`Address`.`address_company_name`) as soundex_address_company_name,
SOUNDEX(`Address`.`contact_name`) as soundex_contact_name,
SOUNDEX(`Address`.`street_address`) as soundex_street_address,
SOUNDEX(`Address`.`suburb`) as soundex_suburb,
SOUNDEX(`Address`.`city`) as soundex_city,
`Address`.`address_country_id`,
`Address`.`address_zone_id`,
`Address`.`postcode`,
COUNT(*)
FROM
`addresses` AS `Address`
WHERE
((`Address`.`address_company_name` IS NOT NULL)
OR (`Address`.`contact_name` IS NOT NULL))
GROUP BY
SOUNDEX(address_company_name),
SOUNDEX(contact_name),
SOUNDEX(street_address),
SOUNDEX(suburb),
SOUNDEX(city),
address_country_id,
address_zone_id,
postcode
HAVING
COUNT(*) > 1
I understand how to do this with multiple queries, ie: loop through each address in our database and then re-query the database for addresses which match any 3 of the 5 columns, however I am hoping to do this in fewer queries as the above query executes very quickly.
I also understand that were this possible, some records may be grouped multiple times, I don't mind if this is the case but I am unsure whether this flies in the face of MySQL logic?
You can try something like this
SELECT a.id, b.id id2, COUNT(*) no_matches
FROM
(
SELECT id,
column_id,
CASE column_id
WHEN 1 THEN SOUNDEX(address_company_name)
WHEN 2 THEN SOUNDEX(contact_name)
WHEN 3 THEN SOUNDEX(street_address)
WHEN 4 THEN SOUNDEX(suburb)
WHEN 5 THEN SOUNDEX(city)
END column_value
FROM addresses a CROSS JOIN
(
SELECT 1 column_id UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5
) i
WHERE address_company_name IS NOT NULL
OR contact_name IS NOT NULL
) a CROSS JOIN
(
SELECT id,
column_id,
CASE column_id
WHEN 1 THEN SOUNDEX(address_company_name)
WHEN 2 THEN SOUNDEX(contact_name)
WHEN 3 THEN SOUNDEX(street_address)
WHEN 4 THEN SOUNDEX(suburb)
WHEN 5 THEN SOUNDEX(city)
END column_value
FROM addresses a CROSS JOIN
(
SELECT 1 column_id UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5
) i
WHERE address_company_name IS NOT NULL
OR contact_name IS NOT NULL
) b
WHERE a.column_value = b.column_value
AND a.id < b.id
GROUP BY a.id, b.id
HAVING COUNT(*) > 2
Sample output:
| ID | ID2 | NO_MATCHES |
|----|-----|------------|
| 1 | 2 | 4 |
| 4 | 5 | 3 |
Here is SQLFiddle demo
Is it possible to select the next lower number from a table without using limit.
Eg: If my table had 10, 3, 2 , 1 I'm trying to select * from table where col > 10.
The result I'm expecting is 3. I know I can use limit 1, but can it be done without that?
Try
SELECT MAX(no) no
FROM table1
WHERE no < 10
Output:
| NO |
------
| 3 |
SQLFiddle
Try this query
SELECT
*
FROM
(SELECT
#rid:=#rid+1 as rId,
a.*
FROM
tbl a
JOIN
(SELECT #rid:=0) b
ORDER BY
id DESC)tmp
WHERE rId=2;
SQL FIDDLE:
| RID | ID | TYPE | DETAILS |
------------------------------------
| 2 | 28 | Twitter | #sqlfiddle5 |
Another approach
select a.* from supportContacts a inner join
(select max(id) as id
from supportContacts
where
id in (select id from supportContacts where id not in
(select max(id) from supportContacts)))b
on a.id=b.id
SQL FIDDLE:
| ID | TYPE | DETAILS |
------------------------------
| 28 | Twitter | #sqlfiddle5 |
Alternatively, this query will always get the second highest number based on the inner where clause.
SELECT *
FROM
(
SELECT t.col,
(
SELECT COUNT(distinct t2.col)
FROM tableName t2
WHERE t2.col >= t.col
) as rank
FROM tablename t
WHERE col <= 10
) xx
WHERE rank = 2 -- <<== means second highest
SQLFiddle Demo
SQLFiddle Demo (supports duplicate values)
If you want to get next lower number from table
you can get it with this query:
SELECT distinct col FROM table1 a
WHERE 2 = (SELECT count(DISTINCT(b.col)) FROM table1 b WHERE a.col >= b.col);
later again if you want to get third lower number you can just pass 3 in place of 2 in where clause
again if you want to get second higher number, just change the condition of where clause in inner query with
a.col <= b.col
Hi there m trying to calculate the row count for same value,
id,value
1 | a
2 | b
3 | c
4 | d
5 | e
and my query is
select value, count(*) as Count from mytable where id in('4','2','4','1','4') group by value having count(*) > 1
for which my expected output will be,
value,Count
d | 3
b | 1
a | 1
Thanks, any help will be appreciated
Try that:
SELECT value, count(value) AS Count
FROM mytable m
WHERE value = m.value
GROUP BY value
SELECT t.id, t.value, COUNT(t.id)
FROM
test t
JOIN
( SELECT 1 AS id
UNION ALL SELECT 3
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 1
UNION ALL SELECT 1 ) AS tmp
ON t.id = tmp.id
GROUP BY t.id
Sample on sqlfiddle.com
See also: Force MySQL to return duplicates from WHERE IN clause without using JOIN/UNION?
Of course, your IN parameter will be dynamic, and thus you will have to generate the corresponding SQL statement for the tmp table.
That's the SQL-only way to do it. Another possibility is to have the query like you have it in your question and afterwards programmatically associate the rows to the count passed to the IN parameter.