The naive way of doing this that comes to mind would be:
SELECT name, lev FROM
(SELECT name, levenshtein(name, *parameter*) as lev FROM my_table)
WHERE
lev = (SELECT MIN(lev) FROM
(SELECT name, levenshtein(name, *parameter*) as lev FROM my_table ));
However the "(SELECT name, levenshtein(name, parameter) as lev FROM my_table)" subquery, which is very expensive (huge table) is repeated twice which seems horribly inefficient.
I somehow though you could write :
SELECT name, lev FROM
(SELECT name, levenshtein(name, *parameter*) as lev FROM my_table) as my_temp_table
WHERE
lev = (SELECT MIN(lev) FROM my_temp_table);
But it doesn't seem to work.
Is there a clean way to optimize that query for speed? Did I miss something obvious?
Do I have to rely on temporary tables?
(trying to avoid it due to the overhead/complexity as they don't seem appropriate for very frequent/concurrent queries)
Any input from SQL ninjas would be greatly appreciated ;)
select * from
(
SELECT *
FROM `test`.`test`
)
as temp
where compute_total_price_single=(select min(compute_total_price_single))
;
This is what I did for my problem, since it worked I suspect the following would also work:
SELECT name, lev FROM
(SELECT name, levenshtein(name, *parameter*) as lev FROM my_table) as my_temp_table
WHERE
lev = (SELECT MIN(lev));
I'm using MySQL 5.
SELECT * FROM
(
SELECT *
FROM `test`.`test`
) as temp
WHERE compute_total_price_single = (SELECT MIN(compute_total_price_single));
SELECT name, min(levenshtein(name, *parameter)) as lev
FROM my_table
GROUP BY name;
Related
This is the result of a UNION of two SELECT
SELECT count(*) FROM
((SELECT session_id_current_user from test.tws_analytics
WHERE (add_date BETWEEN '2022-05-15' AND '2022-05-15') AND ((pathURL='vues/login.php' AND name_current_user='') OR (pathURL='' AND searchURL='?job=forgotten' AND name_current_user=''))
AND session_id_current_user NOT IN
(SELECT session_id_current_user from test.tws_analytics
WHERE (pathURL <> 'vues/login.php' AND searchURL <> '?job=forgotten') AND add_date BETWEEN '2022-05-15' AND '2022-05-15' order by session_id_current_user)
order by session_id_current_user)
UNION
(SELECT name_current_user from test.tws_analytics where add_date BETWEEN '2022-05-15' AND '2022-05-15' AND name_current_user IS NOT NULL AND name_current_user <> ''))
AS tem
The result is 11.
What I want to do is to select this result with other columns like this :
SELECT count(session),count(name), [AND tem.count(*)] FROM ....
This is the general idea, though i didn't know how to implement it.
a simplified general answer would be
select * from (select count(*) numsessions from sessions), (select count(*) numusers from users)
this will give 2 different counts, i didn't include the logics that you provided, but that will need to be done inside the 2 subqueries.
Here is my very simple MYSQL request :
(SELECT start, name, id, info FROM `table1`)
UNION
(SELECT end, name, id, info FROM `table1`)
I want to sort the result by 1st column and I guessed I need to use aliases:
(SELECT start as mydate, name, id, info FROM `table1`)
UNION
(SELECT end as mydate, name, id, info FROM `table1`)
ORDER BY mydate
I was surprised that MYSQL threw this error :
"Unknown column 'mydate' in 'where clause'"
I ended with this working bad practice :
(SELECT start, name, id, info FROM table1)
UNION
(SELECT end, name, id, info FROM table1)
ORDER BY 1
source: https://www.mysqltutorial.org/sql-union-mysql.aspx
But I would like to understand my error !
Use a nested query.
SELECT q.*
FROM (
SELECT start as mydate, name, id, info FROM `table1`
UNION ALL
SELECT end as mydate, name, id, info FROM `table1`
) AS q
ORDER BY q.mydate
The inner query builds up your result set and the outer one orders it. The MySQL query planner is reasonably smart about optimizing this sort of thing.
By the way UNION removes duplicates and UNION ALL does not.
The following shows two attempts at trying to insert data into a temp table using both a union query along with two extra columns (fldBF and sCount)...
CASE 1:
SELECT *, 1 AS fldBF,
ROW_NUMBER() OVER (PARTITION BY fldPK, fldCIA ORDER BY fldPK) AS sCount
INTO #tmpTable
FROM V_qryCSPGA
WHERE fldPK IN(SELECT DISTINCT thePK
FROM FN_qryAllDTPK())
UNION ALL
SELECT *
FROM FN_qryCSGBA()
WHERE fldPK IN(SELECT DISTINCT thePK FROM FN_qryAllDTPK())
ORDER BY fldPK, fldCIA, fldNDat;
CASE 2:
SELECT * INTO #tmpTable
FROM V_qryCSPGA
WHERE fldPK IN(SELECT DISTINCT thePK FROM FN_qryAllDTPK())
UNION ALL
SELECT *, 1 AS fldBF,
ROW_NUMBER() OVER (PARTITION BY fldPK, fldCIA ORDER BY fldPK) AS sCount
FROM FN_qryCSGBA()
WHERE fldPK IN(SELECT DISTINCT thePK FROM FN_qryAllDTPK())
ORDER BY fldPK, fldCIA, fldNDat;
In either case I receive the following error... 'All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.' Is there anyway for me to circumvent this without having to do a whole other insert of some sort?
You need to make sure both select queries are returning equal number of columns. As per comments, if you need to include extra columns, you can add static values to the other select query. So,
Adding (-1) as static values your CASE 1 would be like;
SELECT *, 1 AS fldBF,
ROW_NUMBER() OVER (PARTITION BY fldPK, fldCIA ORDER BY fldPK) AS sCount
INTO #tmpTable
FROM V_qryCSPGA
WHERE fldPK IN(SELECT DISTINCT thePK FROM FN_qryAllDTPK())
UNION ALL
SELECT *, -1 AS fldBF, -1 AS sCount --NOTE: Two static fields
FROM FN_qryCSGBA()
WHERE fldPK IN(SELECT DISTINCT thePK FROM FN_qryAllDTPK())
ORDER BY fldPK, fldCIA, fldNDat;
You could do the same thing to the second query.
Your queries are not equivalent. As the error message says, both select statements must contain the same columns. In your first example, only your first select statement has fldBF and sCount. In your second example, only your second query has fldBF and sCount. Because you are using the SELECT * syntax, you also can experience this issue if one table has more/less columns than the other.
You didn't post what the two input tables look like, so I'm going to assume they are slightly different tables. My suggestion would be to use a query like the following.
You may be able to remove the IN statements and use a join, but again I don't know what your tables look like.
SELECT
ROW_NUMBER() OVER(ORDER BY field1) AS custField1,
1 AS myInt,
*
INTO #tmp_tbl
FROM (
SELECT
field1,
field2,
field3,
'X' AS field4
FROM V_qryCSPGA
WHERE my_pk IN (SELECT DISTINCT some_pk FROM My_Fn())
UNION ALL
SELECT
'A' AS field1,
field5 AS field2,
field3,
field4
FROM FN_qryCSGBA()
) X;
People
here is my little problem.
I have three table:
a_names_1
b_names_2
c_names_3
they are same by structure. all of them has two item: name and used
Is there any QUERY to run to get and count all the 'name' that has 'used'=1 from all those three tables together.
I've tried this one, but didn't work:
(SELECT COUNT(*) 'name' from a_names_1) UNION
(SELECT COUNT(*) 'name' from a_names_2) UNION
(SELECT COUNT(*) 'name' from a_names_3) WHERE `used`=1
I'm using PHPMyAdmin for MySQL.
Any Help would be appreciated.. thanks in advance
This query outputs count of distinct names from all tables with used=1
select count(distinct name)
from
(
select name,used from a_names_1 where used=1
union all
select name,used from a_names_2 where used=1
union all
select name,used from a_names_3 where used=1
) t
If you need to SUM all USED for each NAME from all tables and output only with SUM of used=1 then:
select count(*) from
(
select name, SUM(used)
from
(
select name,used from a_names_1
union all
select name,used from a_names_2
union all
select name,used from a_names_3
) t
GROUP BY name
HAVING SUM(used)=1
) t1
select count(*) as name
from
(
select name, used from a_names_1
union
select name, used from a_names_2
union
select name, used from a_names_3) t
where t.used = 1
Probably this is slow, because you lose the index optimizations. What I would do is do the three queries, something like
SELECT SUM('name') AS name_sum
FROM ((SELECT COUNT(*) 'name' from a_names_1 WHERE `used`=1)
UNION (SELECT COUNT(*) 'name' from a_names_2 WHERE `used`=1));
If this doesn't work, it is probably a problem with the usage of name
Maybe you wanted this way:
select count(*) as cnt
from
(
select name from a_names_1 t1 where t1.used = 1
union
select name from a_names_2 t2 where t2.used = 1
union
select name from a_names_3 t3 where t3.used = 1
) t
The straight forward solution;
SELECT SUM(used) FROM (
SELECT used FROM a_names_1 WHERE used=1
UNION ALL
SELECT used FROM a_names_2 WHERE used=1
UNION ALL
SELECT used FROM a_names_3 WHERE used=1
) a
SQLfiddle for testing
An alternative if you have an index on used (and the only values of used are 0 or 1) is to just do the counting using the index;
SELECT SUM(used) total FROM (
SELECT SUM(used) used FROM a_names_1
UNION ALL
SELECT SUM(used) FROM a_names_2
UNION ALL
SELECT SUM(used) FROM a_names_3
) a
SQLfiddle for this example.
If you look at the query plan of the latter query, you can see it uses the indexes effectively.
i have a table MEN in sql server 2008 that contain 150 rows.
how i can show only the even or only the odd rows ?
Check out ROW_NUMBER()
SELECT t.First, t.Last
FROM (
SELECT *, Row_Number() OVER(ORDER BY First, Last) AS RowNumber
--Row_Number() starts with 1
FROM Table1
) t
WHERE t.RowNumber % 2 = 0 --Even
--WHERE t.RowNumber % 2 = 1 --Odd
Assuming your table has auto-numbered field "RowID" and you want to select only records where RowID is even or odd.
To show odd:
Select * from MEN where (RowID % 2) = 1
To show even:
Select * from MEN where (RowID % 2) = 0
FASTER: Bitwise instead of modulus.
select * from MEN where (id&1)=0;
Random question: Do you actually use uppercase table names?
Usually uppercase is reserved for keywords. (By convention)
odd number query:
SELECT *
FROM ( SELECT rownum rn, empno, ename
FROM emp
) temp
WHERE MOD(temp.rn,2) = 1
even number query:
SELECT *
FROM ( SELECT rownum rn, empno, ename
FROM emp
) temp
WHERE MOD(temp.rn,3) = 0
For even values record :
select * from www where mod(salary,2)=0;
For odd values record:
select * from www where mod(salary,2)!=0;
Try this :
odd :
select * from(
SELECT col1, col2, ROW_NUMBER() OVER(ORDER BY col1 DESC) AS 'RowNumber',
FROM table1
) d where (RowNumber % 2) = 1
even :
select * from(
SELECT col1, col2, ROW_NUMBER() OVER(ORDER BY col1 DESC) AS 'RowNumber',
FROM table1
) d where (RowNumber % 2) = 0
SELECT * FROM (SELECT ROW_NUMBER () OVER (ORDER BY sal DESC) row_number, sr,sal FROM empsal) a WHERE (row_number%2) = 1
and
SELECT * FROM (SELECT ROW_NUMBER () OVER (ORDER BY sal DESC) row_number, sr,sal FROM empsal) a WHERE (row_number%2) = 0
SELECT *
FROM
(
SELECT rownum rn, empno, ename
FROM emp
) temp
WHERE MOD(temp.rn,2) = 1
select * from Tablename
where id%2=0
Following is for fetching even number::
Select * from MEN where Men_ID%2=0;
Following is for fetching odd number::
Select * from MEN where Men_ID%2!=0;
Here MEN is your table_name Men_ID is the column in MEN Table.
Try following
SELECT * FROM Worker WHERE MOD (WORKER_ID, 2) <> 0;
Here’s a simple and straightforward answer to your question, (I think).
I am using the TSQL2012 sample database and I am returning only even or odd rows based on “employeeID” in the “HR.Employees” table.
USE TSQL2012;
GO
Return only Even numbers of the employeeID:
SELECT *
FROM HR.Employees
WHERE (empid % 2) = 0;
GO
Return only Odd numbers of the employeeID:
SELECT *
FROM HR.Employees
WHERE (empid % 2) = 1;
GO
Hopefully, that’s the answer you were looking for.
To fetch even records
select *
from (select id,row_number() over (order by id) as r from table_name) T
where mod(r,2)=0;
To fetch odd records
select *
from (select id,row_number() over (order by id) as r from table_name) T
where mod(r,2)=1;
Oracle Database
ODD ROWS
select * from (select mod(rownum,2) as num , employees.* from employees) where num =0;
EVEN ROWS
select * from (select mod(rownum,2) as num , employees.* from employees) where num =1;
To select an odd id from a table:
select * from Table_Name where id%2=1;
To select an even id from a table:
select * from Table_Name where id%2=0;
We can achieve by this
Query To Find ODD Records
/*Query To Find ODD Result using CTE */
WITH EVEN_ODD_RESULT AS
(
select *, ROW_NUMBER() OVER (ORDER BY CountryID) AS ROWNUM
FROM schema.Country_TBL
)
SELECT * FROM EVEN_ODD_RESULT
WHERE (EVEN_ODD_RESULT.ROWNUM % 2) =1
Query To Find EVEN Records
/*Query To Find EVEN Result using CTE */
WITH EVEN_ODD_RESULT AS
(
select *, ROW_NUMBER() OVER (ORDER BY CountryID) AS ROWNUM
FROM schema.Country_TBL
)
SELECT * FROM EVEN_ODD_RESULT
WHERE (EVEN_ODD_RESULT.ROWNUM % 2) = 0
Thank You
for SQL > odd:
select * from id in(select id from employee where id%2=1)
for SQL > Even:
select * from id in(select id from employee where id%2=0).....f5