Why does this MySQL query not work? - sql

mysql
create temporary table t2
select min(id)
from mycontent
group by download_link;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

Your mycontent table may be locked by some other transaction when you trying to select from it.

Maybe try doing them separately.
1) create temporary table t2;
2) select min(id) from mycontent group by download_link;
It's worth a shot.

As I understand group_by, you need to select the grouped fields for the query to make sense. What is it that you try to accomplish?
Imagine this table:
download_link, id
-----------------
'' , 3
'foo' , 3
This, using your query, would select
3
3
and therefor explain your locking problem because row 1 is locked by the transaction already but needs to be replaced by row 2.

Related

Can you force SQL Server to send the WHERE clause to Linked Server?

I'm trying to determine if a table in my SQL Server 2012 database has any records that don't exist in a table that's on a linked Oracle 11g database.
I tried to do this with the following:
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[ORDERS]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511'
The issue is that it never completes because the ORDERS table on the linked server has about 100 million rows and as per the explain plan on SQL Server, it is trying to pull back the entire ORDERS table from the linked server and then apply the WHERE clause.
As per the explain plan, it views the remote table as having an estimated 10000 rows - I assume that's some kind of default if it is unable to get statistics..?
Even running something as simple as this:
select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511'
causes SQL Server to not send the WHERE clause and the query never completes.
I tried to use OPENQUERY however it won't let me add the doc_id to concatenate into the WHERE clause of the query string.
Then I tried to build a select FROM OPENQUERY string in a function but I can't use sp_executesql in a function to run it.
Any help is greatly appreciated.
I think this would logically work for you, but it may take too long as well.
SELECT sql_ord.*
FROM my_order_table sql_ord
LEFT JOIN LINK_ORA..[SCHEMA1].[ORDERS] ora_ord ON sql_ord.document_id = ora_ord.doc_id
WHERE sql_ord.document_id = 'N2324JKL3511'
AND ora_ord.doc_id IS NULL
Since you have problem with something as simple as select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511' have you try to create a table on the remote server that will hold the doc_id that you want to look at. So your SELECT will include a table that contain only 1 row. I'm just not sure about the INSERT since I can't test it for now. I'm assuming that everything will be done on the remote server.
So something like :
CREATE TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id (
doc_id nvarchar(12));
INSERT INTO LINK_ORA..[SCHEMA1].linked_server_doc_id (doc_id)
SELECT doc_id
FROM LINK_ORA..[SCHEMA1].[ORDERS] WHERE doc_id = 'N2324JKL3511';
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[linked_server_doc_id]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511';
DROP TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id

SQLite: detect if a rowid exists

What's the best/right/fastest/most appropriate way to detect if a row with a given rowid exists?
Or by extension, hwo to detect if at least one row matching a given condition exists?
I'm firing quite some of these requests. I am currently using
SELECT 1 FROM table WHERE condition LIMIT 1
looks a bit weird to me, but looks to me like "the least work" for the db, however, my SQL knowledge is spotty.
I would probably do it something like this:
SELECT
CASE
WHEN EXISTS(SELECT NULL FROM table1 WHERE ID=someid)
THEN 1
ELSE 0
END
To Count the rows is not that effective.
To check if something exists is in most cases more effective
Since it's sqlite, you need to use the column name "rowid" to access that id column. Using Craig Ringer's sql, the sqlite version would look like this:
SELECT EXISTS(SELECT 1 FROM table WHERE rowid = insert_number)
Use EXISTS, it sounds perfect for what you are after. e.g.
SELECT *
FROM T1
WHERE EXISTS (SELECT 1 FROM T2 WHERE T2.X = T1.X AND T2.Y = 1)
It is effectly the same as LIMIT 1 but is generally optimised better.
One could test
select true from table where id = id1
You can for example use
SELECT COUNT(*) FROM table WHERE ID = whatever

Sql Server CE can I delete TOP or only 1 record from table that matches my query

select Top(1)* from TableName Where columnName=value
selects only the first row just fine. However if I change the select to a delete I get an error and can't figure out how to write a query to delete only 1 record that matches my query from the db.
I'm wondering if anybody out there smarter than I knows if or how this can be done in SQL CE.
Did you try something like this?
DELETE TableName where IdColumn In ( select Top(1) IdColumn from TableName Where columnName=valuev)
I don't know specifically as I'm at home, but SQL CE is deliberately restricted in what it can do. One reason for this is that it is 'always' running locally to the process referencing it.
What means is that it is Expected that the other process is expected to handle much of the logic that may otherwise be encapsulated in the SQL Server. This often results in firing several queries at the SQL CE instance, where you may be more accustomed to firing off one.
In this case, you could do it with two queries...
1) A query to identify the record that you want to delete
2) Use that Identifier in another query to do the actual delete
You could also try using SET ROWCOUNT 1 to limit the DELETE to just 1 row. But again, I don't know if that works in CE.
You can use CTE such as
;with myTopRow(rowID)
(
select Top 1 rowID from TableName Where columnName=value
)
delete from TableName inner join myTopRow on TableName.rowID = myTopRow.rowID
Shouldn't it be rather :
DELETE FROM TableName WHERE columnName=value ORDER BY columnName LIMIT 1;
IMHO, the table logically has NO order by itself. It has it physically, but you can't rely on it. So, you HAVE to set the order in which you want to delete the first row.
The following code will delete only first row
Dim mySqlCommondDelete As String = "DELETE BOOK_ID, MemberID FROM (SELECT TOP 1 * FROM ISSUE_BOOK) where BOOK_ID = Val(" & deleteBook & ") and MemberID = Val(" & msk & ")"

Fastest check if row exists in PostgreSQL

I have a bunch of rows that I need to insert into table, but these inserts are always done in batches. So I want to check if a single row from the batch exists in the table because then I know they all were inserted.
So its not a primary key check, but shouldn't matter too much. I would like to only check single row so count(*) probably isn't good, so its something like exists I guess.
But since I'm fairly new to PostgreSQL I'd rather ask people who know.
My batch contains rows with following structure:
userid | rightid | remaining_count
So if table contains any rows with provided userid it means they all are present there.
Use the EXISTS key word for TRUE / FALSE return:
select exists(select 1 from contact where id=12)
How about simply:
select 1 from tbl where userid = 123 limit 1;
where 123 is the userid of the batch that you're about to insert.
The above query will return either an empty set or a single row, depending on whether there are records with the given userid.
If this turns out to be too slow, you could look into creating an index on tbl.userid.
if even a single row from batch exists in table, in that case I
don't have to insert my rows because I know for sure they all were
inserted.
For this to remain true even if your program gets interrupted mid-batch, I'd recommend that you make sure you manage database transactions appropriately (i.e. that the entire batch gets inserted within a single transaction).
INSERT INTO target( userid, rightid, count )
SELECT userid, rightid, count
FROM batch
WHERE NOT EXISTS (
SELECT * FROM target t2, batch b2
WHERE t2.userid = b2.userid
-- ... other keyfields ...
)
;
BTW: if you want the whole batch to fail in case of a duplicate, then (given a primary key constraint)
INSERT INTO target( userid, rightid, count )
SELECT userid, rightid, count
FROM batch
;
will do exactly what you want: either it succeeds, or it fails.
If you think about the performace ,may be you can use "PERFORM" in a function just like this:
PERFORM 1 FROM skytf.test_2 WHERE id=i LIMIT 1;
IF FOUND THEN
RAISE NOTICE ' found record id=%', i;
ELSE
RAISE NOTICE ' not found record id=%', i;
END IF;
as #MikeM pointed out.
select exists(select 1 from contact where id=12)
with index on contact, it can usually reduce time cost to 1 ms.
CREATE INDEX index_contact on contact(id);
SELECT 1 FROM user_right where userid = ? LIMIT 1
If your resultset contains a row then you do not have to insert. Otherwise insert your records.
select true from tablename where condition limit 1;
I believe that this is the query that postgres uses for checking foreign keys.
In your case, you could do this in one go too:
insert into yourtable select $userid, $rightid, $count where not (select true from yourtable where userid = $userid limit 1);

Check number of records in a database table other than count(*)

I want to check if there are any records in a table for a certain entry. I used COUNT(*) to check the number of records and got it to work. However, when the number of records for an entry is very high, my page loads slowly.
I guess COUNT(*) is causing the problem, but how do I check if the records exist without using it? I only want to check whether any records exist for the entry and then execute some code. Please help me find an alternative solution for this.
Thanks for any help.
There are several ways that may work. You can use exists, which lets the database optimise the method to get the answer:
if exists(select * from ...)
You can use top 1 so that the database can stop after finding the first match:
if (select count(*) from (select top 1 * from ...)) > 0
use select top 1 and check is there is an row
You can try selecting the first entry for given condition.
SELECT id FROM table WHERE <condition> LIMIT 1
I'm not sure if this will be quicker but you can try.
Other possible solution. How do you use count? COUNT(*)? If yes, then try using COUNT(id). As I remember this should be faster.
I would recommend testing to see if at least 1 record exists in the table, that meets your criteria then continue accordingly. For example:
IF EXISTS
(
SELECT TOP 1 Table_Name --Or Your ColumnName
FROM INFORMATION_SCHEMA.Tables -- Or your TableName
)
BEGIN
PRINT 'At least one record exists in table'
END
I found this on codeproject. It's quite handy.
-- Author,,Md. Marufuzzaman
SELECT SYS_OBJ.NAME AS "TABLE NAME"
, SYS_INDX.ROWCNT AS "ROW COUNT"
FROM SYSOBJECTS SYS_OBJ, SYSINDEXES SYS_INDX
WHERE SYS_INDX.ID = SYS_OBJ.ID
AND INDID IN(0,1) --This specifies 'user' databases only
AND XTYPE = 'U' --This omits the diagrams table of the database
--You may find other system tables will need to be ommitted,
AND SYS_OBJ.NAME <> 'SYSDIAGRAMS'
ORDER BY SYS_INDX.rowcnt DESC --I found it more useful to display
--The following line adds up all the rowcount results and places
--the final result into a separate column [below the first resulting table]
COMPUTE SUM(SYS_INDX.ROWCNT)
GO
you should use
select count(1) from
If you are saying (*) it will expand all the column's and then count