SQLite How to fetch every column after the 5th - sql

Lets say i have the following sql table named urls:
url
redirect
revenue
realRevenue
clicksGermany
clicksUSA
clicksIndia
gaxktgq
google.com
0.321
69.51
15
28
33
oqjkgf1
example.cn
0.252
1424.3
1202
10
69
gaxktgq
corn.shop
1.242
42525.2
325525
1230
420
Now i want to fetch every column after realRevenue.
In this example you could just fetch by using the names of the columns that come after realRevenue but in my case there are way more fields that come after.
What query do i need?

If the fields you have correspond to the ones presented in your sample input, you should directly select those who are needed by you. If they're more than what we see here, check the next part.
As long as SQLite does not support dynamic queries, you can't create a query in an automatical way.
Although you can retrieve your table interesting fields by accessing the two tables "sqlite_master" and "pragma_table_info", that contains information regarding your table name and table fields respectively. By filtering on the table name and on the field id, you can have a list of all your fields.
SELECT p.name AS column_name
FROM sqlite_master AS m
JOIN pragma_table_info(m.name) AS p ON m.name = 'tab' AND p.cid >= 4
Output:
column_name
clicksGermany
clicksUSA
clicksIndia
But you can also have them prepared to be hardcoded into a SELECT statement, applying a GROUP_CONCAT on the concatenation of the table name and each table field.
SELECT GROUP_CONCAT(m.name || '.' || p.name, ', ') AS fields
FROM sqlite_master AS m
JOIN pragma_table_info(m.name) AS p ON m.name = 'tab' AND p.cid >= 4
fields
tab.clicksGermany, tab.clicksUSA, tab.clicksIndia
Check the demo here.
Note: This solution gets useful if your amount of fields is very big, such that writing all of them by hand becomes a time-consuming task.

Related

Get data from other table based on column with concatenated values

I have two tables:
category with columns:
id name
1 business
2 sports
...
article with columns:
id title categories
1 abc 1|2|3
2 xyz 1|2
I know there should be a separate table for article categories but I was given this.
Is it possible to write a query that returns:
id title category_names
1 xyz business,sports
I thought of splitting the string in article -> categories column, then use in query to extract name from category table but couldn't figure it out.
You should fix your data model. But, you can do this in SQL Server:
select a.*, s.names
from article a cross apply
(select string_agg(c.name, ',') as names
from string_split(a.categories, '|') ss join
category c
on try_convert(int, ss.value) = c.id
) s;
Here is a db<>fiddle.
Presumably, you already know the shortcomings of this data model:
SQL Server has poor string handling functionality.
Numbers should be stored as numbers not strings.
Foreign key references should be properly declared.
Such queries cannot make use of indexes and partitions.
If you really want to store multiple values in a field, SQL Server offers both JSON and XML. Strings are not the right approach.

Need query to list rows where two columns are relatively the same with caveat in Postgresql

Most compare two or more columns for the same value between two tables. I need to compare two columns in a table where relative to another column with 3 owner values used. This will be 3 different first names.
I have seen table compares, but this is in one table and data is separated already by a column value. The table is thousands of rows. Owner column is only three different names.
So Joe, Sam and Jim have rows of names. When any of these two people have a common first and last name listed in the row, they will be listed as output with other column data like location and zip. So if Joe and Sam have two common names, the output will list:
Owner,firstname,lastname,location,zip
Joe,Bob,Smith,Dallas,37377
Sam,Bob,Smith,Dallas,37377
Jim had no Bob,Smith,Dallas,37377 so it is not listed in the group with Joe and Sam. In summation, the results will be a few hundred lines of these 3 owners grouped where a common name is found. I will need to use percentages in the query in case some one uses Bobby or Smiths. Therefore a name like Smithson will show up but I will adjust.
I had this all typed out and the page sees it as code so I apologize I had to abbreviate.
The most straightforward thing to use is a self-join, though an EXISTS may be quicker.
First, the self-join:
--note DISTINCT here because if Joe, Bob, and Sam all have records with the name we don't want duplicates
select DISTINCT f.owner, f.firstname, f.lastname, f.location, f.zip
from tablename f
join tablename s on f.firstname = s.firstname and f.lastname = s.lastname and f.owner <> s.owner
Then, with an EXISTS:
select f.owner, f.firstname, f.lastname, f.location, f.zip
from tablename f
WHERE EXISTS(select 1 from tablename s WHERE s.firstname = f.firstname and s.lastname = f.lastname and s.owner <> f.owner)
Of course, if instead of equality you want 'Smith' and 'smithson' to match, you can replace the equality comparison with something like: (f.firstname ilike (s.firstname||'%') OR s.firstname ilike (f.firstname||'%')) you can use that (or any other comparison)

Create Update Statement that uses Joins or Groups

As part of a larger store procedure I am trying to write a SQL command to update a particular field with a value depending on certain criteria. The issue I have is around linking Joins with Groups.
There are 3 tables involved the initial table holds the ID of the master record in the stored procedure and contains a unique value.
wrec_id
1
2
3
4
The second table may contain entries linked to the master table
Work_id and acts as a route to the Person Table.
If it does not contain a value or the value of pers_id is set to 0 then I need 'Not Assigned' as the Persons Name.
If more than one person has been allocated, then I need a concatenated list of all the people.
wrec_id, pers_id
1, 1
1, 2
2, 1
3, 3
The Person table contains the entries required in the stored procedure.
pers_id, Forename, Surname
1, For1, Sur1
2, For2, Sur2
3, For3, Sur3
The output expected for the above examples should look as follows :-
For1 Sur1 : For2 Sur2
For1 Sur1
For3 Sur3
Not Assigned
I have tried various combinations of Groups and Joins without success.
Any help most welcome.
In SQL Server, you can use the XML PATH expression to combine multiple rows. In this case, you can use something like the query here to show the people assigned to each work project. Then, depending on how you need to use the data, you could handle it either in SQL Server or the calling application. For example, if you're only going to be showing the final results as you have it in the calling application, you could use XSLT to display the XML the way you wanted (if you go this route, you could wrap the entire query in a FOR XML expresion, and display it however you wanted).
If you absolutely need to display the data as you have it in SQL Server, you can instead do something like this:
select
wrec_id
,case
when
( select
' : ' + Persons.Forename + ' ' + Persons.Surname
from WorkAssignments
inner join Persons on
Persons.pers_id = WorkAssignments.pers_id
where
WorkAssignments.wrec_id = WorkProjects.wrec_id
for xml path('')
) is null then 'Not Assigned'
else
( select
' : ' + Persons.Forename + ' ' + Persons.Surname
from WorkAssignments
inner join Persons on
Persons.pers_id = WorkAssignments.pers_id
where
WorkAssignments.wrec_id = WorkProjects.wrec_id
for xml path('')
)
end AssignedPersons
from WorkProjects
Although, as you can see, it starts to get a bit ugly. Again, if you can, you might want to leave the niceties of how to display work assignments to your calling application, rather than doing it directly in SQL Server.

postgresql transpose with different attribute row

This is the first time i used transpose
so i dont know if what i want is possible or not
this is my query
SELECT *
FROM crosstab(
'select p.name, a.attributekey, a.attributevalue
from productz p
join attribute a on a.itemid=p.id
order by p.name, a.attributekey')
AS final_result(name varchar, interface varchar, negativemargin varchar,parity varchar);
select p.name, a.attributekey, a.attributevalue
from productz p
join attribute a on a.itemid=p.id
order by p.name, a.attributekey;
here's the link
http://rextester.com/IQNSY51011
but the output is different than what i want, because productz 1 have two row and the productz 2 have 3 row
name interface negativemargin parity
dufan true true NULL
waterboom android true false
the output i want is this below without insert interface,Null to database
name interface negativemargin parity
dufan NULL true true
waterboom android true false
Note: please click "run it" after opening the link
Solution to your problem:
SELECT *
FROM crosstab(
'select p.name, a.attributekey, a.attributevalue
from productz p
join attribute a on a.itemid=p.id
order by p.name, a.attributekey',
'SELECT DISTINCT attributekey FROM attribute ORDER BY 1')
AS final_result(name varchar, interface varchar, negativemargin varchar,parity varchar);
LINK: http://rextester.com/OPNK82802
Use crosstab(text, text) with 2 input parameters.
The second parameter can be any query that returns one row per attribute matching the order of the column definition at the end.
What is the problem with CROSSTAB(text) i.e. crosstab with 1 parameter?
The main limitation of the single-parameter form of crosstab is that it treats all values in a group alike, inserting each value into the first available column. If you want the value columns to correspond to specific categories of data, and some groups might not have data for some of the categories, that doesn't work well. The two-parameter form of crosstab handles this case by providing an explicit list of the categories corresponding to the output columns.
For more info on crosstab follow the below link:
https://www.postgresql.org/docs/9.2/static/tablefunc.html

Oracle 11 SQL lists and two table comparison

I have a list of 12 strings (strings of numbers) that I need to compare to an existing table in Oracle. However I don't want to create a table just to do the compare; that takes more time than it is worth.
select
column_value as account_number
from
table(sys.odcivarchar2list('27001', '900480', '589358', '130740',
'807958', '579813', '1000100462', '656025',
'11046', '945287', '18193', '897603'))
This provides the correct result.
Now I want to compare that list of 12 against an actual table with account numbers to find the missing values. Normally with two tables I would do a left join table1.account_number = table2.account_number and table two results will have blanks. When I attempt that using the above, all I get are the results where the two records are equal.
select column_value as account_number, k.acct_num
from table(sys.odcivarchar2list('27001',
'900480',
'589358',
'130740',
'807958',
'579813',
'1000100462',
'656025',
'11046',
'945287',
'18193',
'897603'
)) left join
isi_owner.t_known_acct k on column_value = k.acct_num
9 match, but 3 should be included in table1 and blank in table2
Thoughts?
Sean