SELECT the FROM table with a sub select and modify the resulting table name - sql

I have the follwing given two tables which can not be changed.
1: DataTypes
+----------------------+-----------------------+
| datatypename(String) | datatypetable(String) |
+----------------------+-----------------------+
Example data:
+-----------+------------+
| CycleTime | datalong |
+-----------+------------+
| InjTime1 | datadouble |
+-----------+------------+
2: datalong_1 (data model does not matter here)
I want to make a query now that reads the datatypetable attribute from the datatypes table, adds the String "_1" to it and selects all content from it.
I imagined it, from a programmatic perspective, to look something similar to this statement which obviously doesn't work yet:
SELECT * FROM
(SELECT datatypetable FROM datatypes WHERE datatypename = 'CycleTime') + '_1'
How can I make this happen in SQL using HSQLDB?
Thanks to Leonidas199x I know now how to get in the '_1' in but how do I tell the FROM statement that the subselect is not a new table I want to read from but instead the name of an existing table I want to read from.
SELECT * FROM
(SELECT RTRIM(datatypetable)+'_1' FROM datatypes WHERE datatypename = 'CycleTime')
According to this question which is identical to mine this is not possible:
using subquery instead of the tablename
:(

Can you explain your data model in a little more detail? I am not sure I understand exactly what it is you are looking to do.
If you are wanting to add _1 to the 'datatypename', you can use:
SELECT datatypename+'_1'
FROM datatypes

Related

How to get a id value of tables in postgres

How to get a unique, identical value of a table?
For example, if there are tables like 't_aa', 't_bb', 't_cc', I want a result like below.
id | table_name
-------------------
1 | 't_aa'
2 | 't_bb'
3 | 't_cc'
What I exactly want is to get a specific, and unique number from the name of tables.
I have tried
SELECT * FROM information_schema.tables;
-- or
SELECT * FROM pg_catalog.pg_tables;
but this doesn't provide any identical numbers to me.
I hope there is some way to get results like above by using some lines of query,
but if I really have to make a new table for this, that could be okay as an alternative.
please help me, thank you
-- edit
I need numbers because I will use it as an advisory lock key for some reasons.
ThIs is it:
SELECT table_name,ROW_NUMBER () OVER (
ORDER BY table_name
) as id FROM information_schema.tables;

How to create a central parameter, like Report-Date?

I would like to create one location on sql server where I store the report-date and all queries and procedures should relate to this one value.
In that way I only have to change the report date on one location and it is valid for all related queries and procedures.
I started with a scalar function that retrieves a value from a table, but this slows down the queries enomoursly.
I tried an inline table valued function, but have no idea how to include this into a query.
I tried with a table that contains the report-date and used a cross join.
But it says:
The multi-part identifier could not be bound
Maybe some of you have an idea what to do here?
One possibility is to create a table, let's say TblReportDate with two columns: id and reportDate.
Then add one row with id 1 like following:
+----+------------+
| id | reportDate |
+----+------------+
| 1 | 04.04.2018 |
+----+------------+
Now join the table with a LEFT JOIN and use the >= operator to compare with the id-column of the main-table:
SELECT * FROM mainTable
LEFT JOIN TblReportDate ON mainTable.id >= TblReportDate.id

Oracle-SQL Single select, cascade by field

I'm not entirely sure how to phrase what I mean. Let me try: Is there a way to select all elements that cascade by a reference field?
For instance, I have the rows:
parentRef | Reference | Data
------------------------------
aContainer | mainObj | "Parent"
mainObj | secondObj | "Child 1"
secondObj | thirdObj | "Child 2"
nonExistent | blankObj | "Don't select me!"
And I want to select mainObj, secondObj, thirdObj in a single statement when I only know one parentRef: "aContainer". Is this possible?
I could do this by having my code perform many queries: select...where parentRef = 'aContainer', then select...where parentRef = 'mainObj', etc, but I really don't want to hammer my DB with many queries, primarily for speed.
Edit: Tree Queries! That's the search term I needed.
Oracle can do Tree Queries, have a look at START WITH and CONNECT BY
If I understand you right, you want something like a correlated query. This will allow you to get only items that have a parent reference in the table. an example would look something like the following (although I might have reversed the logic):
select
parentRef
, Reference
, Data
from mytable parentTable
where Reference in (
select
reference
from mytable childTable
where childTable.reference = parenttable.parentref)

How do I use variables in a select query?

I have this following select query that uses a scalar function to get full name. I want to eliminate the redundancy by using variable but so far there is no success. My query is
select
a.Id,
a.UserName,
getFullName(a.UserName),
a.CreateTime
from DataTable;
I don't want to retrieve 'a.User' two times. I would prefer if I can save a.User in a variable and then pass it to the function hence improving the efficiency.
Currently the work around I came up with is as following
select
Id,
UserName,
getFullName(UserName),
CreateTime
from (select a.Id, a.UserName, a.CreateTime from DataTable) temp
This solves the performance issue but adds the overhead to write same select two time. Any other suggestions would be great.
DataTable looks like this
+----+----------+------------+
| Id | UserName | CreateTime |
+----+----------+------------+
| 1 | ab | 10:00 |
| 2 | cd | 11:00 |
| 3 | ef | 12:00 |
+----+----------+------------+
Here is the NamesTable used to get the full names
+----------+----------+
| UserName | FullName |
+----------+----------+
| ab | Aa BB |
| cd | Cc Dd |
| ef | Ee Ff |
+----------+----------+
Here is the function that gets the full name
Create function [dbo].[getFullName](#user varchar(150)) returns varchar(500)
as
begin
declare #Result varchar(500);
select #Result = FullName from dbo.NamesTable where UserName = #user;
return #Result;
end;
You're solving a problem that doesn't exist. You seem to think that
select
a.Id,
a.UserName,
getFullName(a.UserName),
a.CreateTime
from DataTable;
Has some relatively expensive process behind it to get UserName that is happening twice. In reality, once the record is located, getting the UserName value is an virtually instant process since it will probably be stored in a "variable" by the SQL engine behind the scenes. You should have little to no performance difference between that query and
select
a.Id,
getFullName(a.UserName),
a.CreateTime
from DataTable;
The scalar function itself may have a performance issue, but it's not because you are "pulling" the UserName value "twice".
A better method would be to join to the other table:
select
a.Id,
a.UserName,
b.FullName,
a.CreateTime
from DataTable a
LEFT JOIN dbo.NamesTable b
ON a.UserName = b.UserName
As D Stanley says, you're trying to solve some problem that doesn't exist. I would further add that you shouldn't be using the function at all. SQL is meant to perform set-based operations. When you use a function like that you're now making it perform the same function over and over again for every row - a horrible practice. Instead, just JOIN in the other table (a set-based operation) and let SQL do what it does best:
SELECT
DT.Id,
DT.UserName,
NT.fullname,
DT.CreateTime
FROM
DataTable DT
INNER JOIN NamesTable NT ON NT.username = DT.username;
Also, DataTable and NamesTable are terrible names for tables. Of course they're tables, so there's no need to put "table" on the end of the name. Further, of course the first one holds "data", it's a database. Your table names should be descriptive. What exactly does DataTable hold?
If you're going to be doing SQL development in the future then I strongly suggest that you read several introductory books on the subject and watch as many tutorial videos as you can find.
Scalar UDF will execute for every row,but not defintely the way you think.below is sample demo and execution plan which proves the same..
create table testid
(
id int,
name varchar(20)
)
insert into testid
select n,'abc'
from numbers
where n<=1000000
create index nci_get on dbo.testid(id,name)
select id,name,dbo.getusername(id) from dbo.testid where id>4
below is the execution plan for above query
Decoding above plan:
Index seek outputs id,name
Then compute scalar tries to calculate new rows from existing row values.in this case expr1003 which is our function
Index seek cost is 97%,compute scalar cost is 3% and as you might be aware index seek is not an operator which goes to table to get data.so hopefully this clears your question

Counting Distinct Values in large dataset (40M rows): SELECT count(*) as count, name FROM names GROUP BY name ORDER BY name;

CREATE TABLE `names` ( `name` varchar(20) );
Assume the names table contains all 40 million first names of everyone living in California (for example).
SELECT count(*) as count, name FROM names GROUP BY name ORDER BY name;
How can I optimize this query?
Expected Result:
count | name
9999 | joe
9995 | mike
9990 | kate
.... | ....
2 | kal-el
You have to create an index on the name column of your table. The query is as good as it can be.
Well, what makes you think it's not already optimised? This looks like the sort of query a good database engine should be able to handle relatively easily - particularly if you've got an appropriate index on your table.
Do you actually have a bottleneck here, or are you worrying about something that might happen in the future? If it's the latter, I suggest you try it with your RDBMS (by generating dummy data), and see what happens.