I'm trying to convert this MySQL query to SQL Server, but I do not know much about SQL Server
SELECT
*
FROM
Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.Column1 = T2.ColumnX
WHERE
T1.ColumnY = 'xxxx'
GROUP BY
T1.Column1
Somebody can help me?
Your query is just an erroneous query, because you are using select * with group by. This query uses a MySQL extension. And, the default settings in more recent versions of MySQL would generate an error.
Here is one method for converting this to SQL Server:
SELECT TOP (1) WITH TIES *
FROM Table1 AS T1 INNER JOIN
Table2 AS T2
ON T1.Column1 = T2.ColumnX
WHERE T1.ColumnY = 'xxxx'
ORDER BY ROW_NUMBER() OVER (PARTITION BY T1.Column1 ORDER BY (SELECT NULL)) ;
Probably a better method (from a performance perspective) uses a lateral join:
SELECT *
FROM Table1 T1 CROSS APPLY
(SELECT TOP (1) T2.*
FROM Table2 T2
WHERE T1.Column1 = T2.ColumnX
) T2
WHERE T1.ColumnY = 'xxxx' ;
Both of these choose arbitrary rows from Table2 when there is more than one match.
Related
I have a weird situation here that I try to resolve through SQL so I don't have to modify much in the application :).
Is there ANY way that I can tell if a column exists in a quere within the query?
(Table2 is not always joined in the query)
SELECT * FROM
Table1 as T1
join Table2 as T2 on t1.id = t2.fk
WHERE
T1.something > 10 OR (IF(table and column exists in the query T2.col, 1, 0);
my alternative is to always join Table2 (painful in this case).
Any SQL guru/genius can help?
I solved the problem with an easy work around. So, for the sake of referencing...
SELECT *
FROM Table1 as T1
WHERE T1.something > 10 OR ((SELECT ....) = 1)
I wrote a query in this format..
Select * INTO #xyz FROM ()
which I later want to use to create a view, as...
CREATE VIEW aaa
AS
Select * INTO #xyz FROM ()
but getting the following errors:
Incorrect syntax near the keyword 'INTO'.
Views or functions are not allowed on temporary tables
Can someone please suggest a workaround this? Is it possible to use temporary tables to create views?
You certainly cannot use a select into in a view. And a termp table is not approraite either. Use a derived table that is the equivalent of the temp table instead. Example:
Suppose you had:
select t1.id, t2.field1 into #temp from table1 t1
join Table2 t2 on t1.id = t2.id
where t2.somefield2 = 'mytest'
select t1.id, t2.field1, t1.field1
from mytable2 t1
join #Temp t2 on t1.id = t2.id
where t2.somefield = 'test'
Then you could use:
select t1.id, t2.field1, t1.field1
from mytable2 t1
join (select t1.id, t2.field1
from table1 t1
join Table2 t2 on t1.id = t2.id
where t2.somefield2 = 'mytest') t2
on t1.id = t2.id
where t2.somefield = 'test'
You could also usea a CTE
Just as the error message says it is not possible to use temp tables.
You should use a permanent table or a CTE which can also be specified in a view.
A CTE could help you out depending on your situation. Describe your problem with some context if you think it suitable after researching what a CTE is. In short a CTE is a query that you can reference multiple times which in the past people used temp tables for.
http://msdn.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
Is there any major difference from an optimisation point of view between the following two alternatives? In the first option I alias the table, so the total_paid calculation is only run once. In the second option, there is no table alias, but the SUM calculation is required a few times.
Option 1
SELECT tt.*, tt.amount - tt.total_paid as outstanding
FROM
(
SELECT t1.id, t1.amount, SUM(t2.paid) as total_paid
FROM table1 t1
LEFT JOIN table2 t2 on t1.id = t2.t1_id
GROUP BY t1.id
) as temp_table tt
WHERE (tt.amount - tt.total_paid) > 0
LIMIT 0, 25
Option 2
SELECT t1.id, t1.amount, SUM(t2.paid) as total_paid
, (t1.amount - SUM(t2.paid)) as outstanding
FROM table1 t1
LEFT JOIN table2 t2 on t1.id = t2.t1_id
WHERE (t1.amount - SUM(t2.paid)) > 0
GROUP BY t1.id
LIMIT 0, 25
Or perhaps there is an even better option?
if you run the queries with EXPLAIN, you'll be able to see what's going on 'inside'.
Also, why don't you just run it and compare the execution times?
Read more on explain here
SELECT count( t1.id ) , t2.special_value
FROM table_1 AS t1, table_2 AS t2
WHERE t1.`group` = 'val'
AND t2.code = 'val'
returns
count - normal value
special_value - NULL
but
SELECT t2.special_value
FROM table_2 AS t2
WHERE t2.code = 'val'
returns
special_value - another normal value
why first query works wrong?..
currently, i need
(count( t1.id ) + t2.special_value)
This is why you should never use SQL'89 implicit join syntax.
You have no join condition resulting in a cross join.
Rewrite the query using explicit join syntax:
SELECT count( t1.id ) , t2.special_value
FROM table_1 AS t1
INNER JOIN table_2 AS t2 ON (t1.`group` = t2.code) <<-- join condition here
WHERE .... <<-- filter condition here
GROUP BY .... <<-- group by field here
I don't know how table t1 and t2 are linked, so you'll have to tweak this a bit, but that's how it supposed to work.
And please never ever use implicit where joins again.
Remarks
I'm wondering what p.`group` and pp.code are, but I'm guessing you meant to write t1.`group` and t2.code
You only need to escape fields and tablenames in ` backticks if they are reserved words.
Personally all those backticks make me dizzy, but that's just me.
Here is my code:
SELECT field1, field2,
(SELECT * FROM table1 WHERE a = field2),
(SELECT COUNT(*)
FROM (SELECT *
FROM table2
WHERE c = field2) as t1) as count
FROM table3;
...and here is error message:
/* SQL Error (1054): Unknown column
'field2' in 'where clause' */
I want to execute one query, to get table2's total counts.
The problem is that you're trying to use a variable declared in the outer query in the inner query. Variables are scoped the opposite way in SQL, you only have access to inner queries. What you want to do (I believe) is look for the number of table2 that have a c that matches the a from table1. This should give you that answer.
SELECT
table1.a,
table2.c,
count(*)
FROM
table1
JOIN
table2 ON table2.c = table1.a
GROUP BY
table1.a
I re-wrote your query as:
SELECT t3.field1,
t3.field2,
t1.*,
t2.cnt
FROM TABLE3 t3
LEFT JOIN TABLE1 t1 ON t1.a = t3.field2
LEFT JOIN (SELECT t.c,
COUNT(*) AS cnt
FROM TABLE2 t
GROUP BY t.c) t2 ON t2.c = t3.field2
The 1054 error is due to referencing field2 two subqueries deep - most only support one level deep.
UPDATE:
I want to edit the answer, since in MySQL 8.0 your query is already correct, derived tables can access external references no matter the level.
SELECT field1, field2,
(SELECT 'hola' FROM table1 WHERE a = field2),
(SELECT COUNT(*)
FROM (SELECT *
FROM table2
WHERE c = field2) as t1) as count
FROM table3;
"Prior to MySQL 8.0.14, a derived table cannot contain outer references. This is a MySQL restriction that is lifted in MySQL 8.0.14, not a restriction of the SQL standard. For example, the derived table dt in the following query contains a reference t1.b to the table t1 in the outer query:" https://dev.mysql.com/doc/refman/8.0/en/derived-tables.html