It seems a basic questions but after several hours and days, i'm still blocked.
As part of a query I would like to select some specific rows in a table (actually this table is already a query). As an example, rows are highlighted in the picture attached. For each "batch", this corresponds to the row containing the lower "CountofVials" and is not a "Stability rack".
How would you create the query? I usually use the Design view to create query but i can understand SQL too.
table with rows to select in yellow
SELECT *
FROM YourQuery a
WHERE EXISTS (SELECT 1
From YourQuery b
WHERE b.[Stability Rack] = False AND b.Batch=a.Batch
GROUP BY Batch
HAVING Min(CountOfVial)=a.CountOfVial )
You cannot 'select' non-contiguous in Access. You can use a form and 'highlight' entire rows or individual values using conditional formatting. There has been much posted on conditional formatting, so it would be best to just look it up.
Related
I have a table called "dutyroster". I want to make a random selection from this table's "names" column, but, I want the selection be different than the last 10 records so that the same guy is not given a second duty in 10 days. Is that possible ?
Create a temporary table with only one column called oldnames which will have no records initially. For each select, execute a query like
select names from dutyroster where dutyroster.names not in (select oldnamesfrom temporarytable) limit 10
and when execution is done add the resultset to the temporary table
The other answer already here is addressing the portion of the question on how to avoid duplicating selections.
To accomplish the random part of the selection, leverage newid() directly within your select statement. I've made this sqlfiddle as an example.
SELECT TOP 10
newid() AS [RandomSortColumn],
*
FROM
dutyroster
ORDER BY
[RandomSortColumn] ASC
Keep executing the query, and you'll keep getting different results. Use the technique in the other answer for avoiding doubling a guy up.
The basic idea is to use a subquery to get all but users from the last ten days, then sort the rest randomly:
select dr.*
from dutyroster dr
where dr.name not in (select dr2.name
from dutyroster dr2
where dr2.datetimecol >= date_sub(curdate(), interval 10 day)
)
order by rand()
limit 1;
Different databases may have different syntax for limit, rand(), and for the date/time functions. The above gives the structure of the query, but the functions may differ.
If you have a large amount of data and performance is a concern, there are other (more complicated) ways to take a random sample.
you could use TOP function for SQL Server
and for MYSQL you could use LIMIT function
Maybe this would help...
SELECT TOP number|percent column_name(s)
FROM table_name;
Source: http://www.w3schools.com/sql/sql_top.asp
In SQL Server, I can do this with the help of Cursor (to loop through each row in the result set and build my string). But I don't know how to do the same in SQLite, this task is not like the so-called Pivoting which as far as I know, we have to know the exact rows we want to turn to columns. My case is different, I want to select all the values of a specified column into a string (and then can select as a column of 1 row), this column can have various values depend on the SELECT query. Here is a sample of how it looks:
A | B
------------
1 | 0
8 | 1
3 | 2
... ....
I want to select all the values of the column A into a string like this "183..." (or "1,8,3,..." would be fine).
This can be used as a column in another SELECT, I have to implement this because I need to display all the sub-infos (on each row of column A) as a comma-separated list in another row.
I don't have any idea on this, it seems to need some procedural statements (such as placed in a procedure) but SQLite limits much on how I can do with loop, variable declaration,...I'm really stuck. This kind of task is very common when programming database and there is no reason for me to refuse doing it.
Please help, your help would be highly appreciated! Thanks!
If you're just trying to get all the values from Column A into a single record, then use GROUP_CONCAT:
select group_concat(a, ',')
from yourtable
SQL Fiddle Demo
The main problem is that you are think like an application programmer. SQL does a lot of things for you.
SELECT *
FROM tableA
WHERE A IN (SELECT A
FROM tableB)
No need to resort to cursors, stored procedures and multiple queries.
I have a database, database1, with two tables (Table 1, Table2) in it.
There are 3 rows in Table1 and 2 rows in Table2. Now if I execute the following SQL query SELECT COUNT(*); on database1, then the output is "1".
Does anyone has the idea, what this "1" signifies?
The definition of the two tables is as below.
CREATE TABLE Table1
(
ID INT PRIMARY KEY,
NAME NVARCHAR(20)
)
CREATE TABLE Table2
(
ID INT PRIMARY KEY,
NAME NVARCHAR(20)
)
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT(*) you did the equivalent of SELECT COUNT(*) FROM ImaginaryTableWithOneRow which of course returns 1.
Along similar lines the following also returns a result.
SELECT 'test'
WHERE EXISTS (SELECT *)
The explanation for that behavior (from this Connect item) also applies to your question.
In ANSI SQL, a SELECT statement without FROM clause is not permitted -
you need to specify a table source. So the statement "SELECT 'test'
WHERE EXISTS(SELECT *)" should give syntax error. This is the correct
behavior.
With respect to the SQL Server implementation, the FROM
clause is optional and it has always worked this way. So you can do
"SELECT 1" or "SELECT #v" and so on without requiring a table. In
other database systems, there is a dummy table called "DUAL" with one
row that is used to do such SELECT statements like "SELECT 1 FROM
dual;" or "SELECT #v FROM dual;". Now, coming to the EXISTS clause -
the project list doesn't matter in terms of the syntax or result of
the query and SELECT * is valid in a sub-query. Couple this with the
fact that we allow SELECT without FROM, you get the behavior that you
see. We could fix it but there is not much value in doing it and it
might break existing application code.
It's because you have executed select count(*) without specifying a table.
The count function returns the number of rows in the specified dataset. If you don't specify a table to select from, a single select will only ever return a single row - therefore count(*) will return 1. (In some versions of SQL, such as Oracle, you have to specify a table or similar database object; Oracle includes a dummy table (called DUAL) which can be selected from when no specific table is required.)
you wouldn't normally execute a select count(*) without specifying a table to query against. Your database server is probably giving you a count of "1" based on default system table it is querying.
Try using
select count(*) from Table1
Without a table name it makes no sense.
without table name it always return 1 whether it any database....
Since this is tagged SQL server, the MSDN states.
COUNT always returns an int data type value.
Also,
COUNT(*) returns the number of items in a group. This includes NULL
values and duplicates.
Thus, since you didn't provide a table to do a COUNT from, the default (assumption) is that it returns a 1.
COUNT function returns the number of rows as result. If you don't specify any table, it returns 1 by default. ie., COUNT(*), COUNT(1), COUNT(2), ... will return 1 always.
Select *
without a from clause is "Select ALL from the Universe" since you have filtered out nothing.
In your case, you are asking "How many universe?"
This is exactly how I would teach it. I would write on the board on the first day,
Select * and ask what it means. Answer: Give me the world.
And from there I would teach how to filter the universe down to something meaningful.
I must admit, I never thought of Select Count(*), which would make it more interesting but still brings back a true answer. We have only one world.
Without consulting Steven Hawking, SQL will have to contend with only 1.
The results of the query is correct.
The typical way of selecting data is:
select * from my_table
But what if the table contains 10 million records and you only want records 300,010 to 300,020
Is there a way to create a SQL statement on Microsoft SQL that only gets 10 records at once?
E.g.
select * from my_table from records 300,010 to 300,020
This would be way more efficient than retrieving 10 million records across the network, storing them in the IIS server and then counting to the records you want.
SELECT * FROM my_table is just the tip of the iceberg. Assuming you're talking a table with an identity field for the primary key, you can just say:
SELECT * FROM my_table WHERE ID >= 300010 AND ID <= 300020
You should also know that selecting * is considered poor practice in many circles. They want you specify the exact column list.
Try looking at info about pagination. Here's a short summary of it for SQL Server.
Absolutely. On MySQL and PostgreSQL (the two databases I've used), the syntax would be
SELECT [columns] FROM table LIMIT 10 OFFSET 300010;
On MS SQL, it's something like SELECT TOP 10 ...; I don't know the syntax for offsetting the record list.
Note that you never want to use SELECT *; it's a maintenance nightmare if anything ever changes. This query, though, is going to be incredibly slow since your database will have to scan through and throw away the first 300,010 records to get to the 10 you want. It'll also be unpredictable, since you haven't told the database which order you want the records in.
This is the core of SQL: tell it which 10 records you want, identified by a key in a specific range, and the database will do its best to grab and return those records with minimal work. Look up any tutorial on SQL for more information on how it works.
When working with large tables, it is often a good idea to make use of Partitioning techniques available in SQL Server.
The rules of your partitition function typically dictate that only a range of data can reside within a given partition. You could split your partitions by date range or ID for example.
In order to select from a particular partition you would use a query similar to the following.
SELECT <Column Name1>…/*
FROM <Table Name>
WHERE $PARTITION.<Partition Function Name>(<Column Name>) = <Partition Number>
Take a look at the following white paper for more detailed infromation on partitioning in SQL Server 2005.
http://msdn.microsoft.com/en-us/library/ms345146.aspx
I hope this helps however please feel free to pose further questions.
Cheers, John
I use wrapper queries to select the core query and then just isolate the ROW numbers that i wish to take from the query - this allows the SQL server to do all the heavy lifting inside the CORE query and just pass out the small amount of the table that i have requested. All you need to do is pass the [start_row_variable] and the [end_row_variable] into the SQL query.
NOTE: The order clause is specified OUTSIDE the core query [sql_order_clause]
w1 and w2 are TEMPORARY table created by the SQL server as the wrapper tables.
SELECT
w1.*
FROM(
SELECT w2.*,
ROW_NUMBER() OVER ([sql_order_clause]) AS ROW
FROM (
<!--- CORE QUERY START --->
SELECT [columns]
FROM [table_name]
WHERE [sql_string]
<!--- CORE QUERY END --->
) AS w2
) AS w1
WHERE ROW BETWEEN [start_row_variable] AND [end_row_variable]
This method has hugely optimized my database systems. It works very well.
IMPORTANT: Be sure to always explicitly specify only the exact columns you wish to retrieve in the core query as fetching unnecessary data in these CORE queries can cost you serious overhead
Use TOP to select only a limited amont of rows like:
SELECT TOP 10 * FROM my_table WHERE ID >= 300010
Add an ORDER BY if you want the results in a particular order.
To be efficient there has to be an index on the ID column.
I am retrieving multiple rows into a listview control from an ODBC source. For simple SELECTs it seems to work well with a statement attribute of SQL_SCROLLABLE. How do I do this with a UNION query (with two selects)?
The most likely server will be MS SQL Server (probably 2005). The code is C for the Win32 API.
This code sets (what I think is) a server side cursor which feeds data into the ODBC driver that roughly corresponds with the positional fetches of SQLFetchScroll, which is turn feeds the cache for the listview. (Sometimes using SQL_FETCH_FIRST or SQL_FETCH_LAST as well as):
SQLSetStmtAttr(hstmt1Fetch,
SQL_ATTR_CURSOR_SCROLLABLE,
(SQLPOINTER)SQL_SCROLLABLE,
SQL_IS_INTEGER);
SQLSetStmtAttr(hstmt1Fetch,
SQL_ATTR_CURSOR_SENSITIVITY,
(SQLPOINTER)SQL_INSENSITIVE,
SQL_IS_INTEGER);
...
retcode = SQLGetStmtAttr(hstmt1Fetch,
SQL_ATTR_ROW_NUMBER,
&CurrentRowNumber,
SQL_IS_UINTEGER,
NULL);
...
retcode = SQLFetchScroll(hstmt1Fetch, SQL_FETCH_ABSOLUTE, Position);
(The above is is a fragment from working code for a single SELECT).
Is this the best way to do it? Given that I need to retrieve the last row to get the number of rows and populate the end buffer is there a better way of doing it? (Can I use forward only scrolling?)
Assuming yes to the above, how do I achieve the same result with a UNION query?
LATE EDIT: The problem with the union query being that effectively it forces forward only scrolling which breaks SQLFetchScroll(hstmt1Fetch, SQL_FETCH_ABSOLUTE, Position). The answer is I suspect: "you can't". And it really means redesigning the DB to included either a view or a single table to replace the UNION. But I'll leave the question open in case I have missed something.
can you not define a view on the db server that does the union query for you, so from the client code it just looks like a single select?
if you can't, can you just issue the union operation as part of your select, e.g.
select some_fields from table1
union
select same_fields from table2
and treat the result as a single result set?
Have you tried using union to make a derived table ?
select * from
(select field1, field from table1
union all
slect field1, filed2 from table2) a
If the issue is just needing to get the last row to get the number of rows and caching the last few rows (I assume if there are a million items in the select that you're not populating a drop-list with all of them) then you may be able to take advantage of the ROW_NUMBER() function of SQL Server 2005
You could:
select count(*)
from (select blah UNION select blah)
to get the number of rows.
Then:
select ROW_NUMBER() as rownum,blah
from (select blah UNION select blah)
where rownum between minrow and maxrow
to just fetch the rows that you need to display/cache
But seriously folks, if you're selecting items from a million-row table, you might want to consider a different mechanism
Good luck!