I have a table with App name, server name and source of that record (3 unique sources). Table can contain same app name, server name but different source for any record, and also sometimes for an app it can be present in one source and not in other. Now I want to find out records for three scenarios.
I am trying to use except but not working, can someone give me query for this.
Table
app
server
source
abc
123
A
abc
123
B
abc
123
C
def
456
A
def
456
B
ghi
789
A
jkl
012
B
jkl
012
C
Scenarios: server in
src A
src B
src C
Action
Yes
Yes
Yes
No action
Yes
No
No
add to B
Yes
Yes
No
add to C
No
Yes
Yes
remove from B and C
Expected Output:
No need to display abc 123 as it is present in all 3 sources
app
server
action
def
456
add to C
ghi
789
add to B
jkl
012
remove from B and C
You can group by app and server and proceed exactly like you describe:
SELECT app, server
CASE
WHEN has_a AND has_b AND has_c
THEN 'No action'
WHEN has_a AND NOT has_b AND NOT has_c
THEN 'add to B'
WHEN has_a AND has_b AND NOT has_c
THEN 'add to C'
WHEN NOT has_a AND has_b AND has_c
THEN 'remove from B and C'
END AS action
FROM (SELECT app, server,
bool_or(source = 'A') AS has_a,
bool_or(source = 'B') AS has_b,
bool_or(source = 'C') AS has_c
FROM tab
GROUP BY app, server) AS grouped;
Note that action will be NULL for those cases not mentioned in your question.
Hello if i have 2 text files like this
file1
jack : 10
donald : 50
mark : 20
florence : 15
ariel : 50
arnold : 50
file2
jack
country : ohaio
donald
country : italy
mark
country : france
florence
country : china
ariel
country :america
arnold
country: japan
how can i to get country names of people older than 20 looping through ages in file1 to get names of people first then after i get names loop through them in file2 to get countries.// don't know how to deal with duplicate ages,this is just sample files there is a lot more values than that.
so output should be something like this:
ages
10
20
50
15
50
50
values over 20
50
50
50
names
donald
ariel
arnold
countries
italy
america
japan
the following code presumes the entries in the two files are in the EXACT same sequence ... and they have EXACTLY the same number of entries. [grin]
what it does ...
sets the name & location of the input files
creates the files to work with
comment out or remove this region when ready to work with real data.
reads in the 1st file as an array of single lines
reads in the 2nd file as an array of 3-line chunks
iterates thru the two collections in parallel using the index number of the 1st collection
the .GetUpperBound(0) gets the upper limit of the zero axis of the collection.
builds a PSCustomObject of the desired items
it uses the $Index to decide what to work on.
the [1] after the Country file index grabs the 2nd line of the 3-line chunk.
sends the PSCO out to the $Results collection
displays it on screen
filters the collection for the items where the .Age property is over 20
the code ...
$File_1_Name = "$env:TEMP\3N16M4_File1.txt"
$File_2_Name = "$env:TEMP\3N16M4_File2.txt"
#region >>> create files to work with
$NameAge = #'
jack : 10
donald : 50
mark : 20
florence : 15
ariel : 50
arnold : 50
'# | Set-Content -LiteralPath $File_1_Name -ErrorAction 'SilentlyContinue'
$NameCountry = #'
jack
country : ohaio
donald
country : italy
mark
country : france
florence
country : china
ariel
country :america
arnold
country: japan
'# | Set-Content -LiteralPath $File_2_Name -ErrorAction 'SilentlyContinue'
#endregion >>> create files to work with
$NameAge = Get-Content -LiteralPath $File_1_Name
# the "-ReadCount" parameter grabs lines in groups
$NameCountry = Get-Content -LiteralPath $File_2_Name -ReadCount 3
# this code presumes the two files are in the EXACT same sequence
# and that they have EXACTLY the same number of entries
$Results = foreach ($Index in 0..$NameAge.GetUpperBound(0))
{
[PSCustomObject]#{
Name = $NameAge[$Index].Split(':')[0].Trim()
Age = $NameAge[$Index].Split(':')[-1].Trim()
Country = ($NameCountry[$Index][1] -replace '(?ms).+:', '').Trim()
}
}
# show whole collection on screen
$Results
'=' * 30
# show the filtered results
$Results.Where({$_.Age -gt 20})
on screen display - the whole collection is above the line, the filtered items are below it ...
Name Age Country
---- --- -------
jack 10 ohaio
donald 50 italy
mark 20 france
florence 15 china
ariel 50 america
arnold 50 japan
==============================
donald 50 italy
ariel 50 america
arnold 50 japan
I have an output in my queries that gives me:
xxxxxxx xxxxxxxxx : 123456 (xx) - xxxxxxx...
or
xxxxxxx xxxxxxxxx : 12345678 (xx) - xxxxxxx...
basically text before either a 6 or 8 digit number then text after.
Ideally I'd like to be able to CASE this column so I'd have an output where it's a 6 digit number = London and the output when it's an 8 digit number = Paris.
But I am very stuck on how to get the CASE statement to achieve this - essentially trim out a lot of text, work out if the number is either 6 or 8 digits long, then tell me if it's London or Paris. I'm not sure if it's possible.
Is this sort of CASE statement achievable? Advise / pointers would be very gratefully received. Thanks very much.
One way to do it is using a common table expression with patindex.
First, create and populate sample table (Please save us this step in your future questions)
DECLARE #T As Table
(
LongText varchar(4000)
)
INSERT INTO #T (LongText) VALUES
('.njauaerigha n uaer gauer 345 gnaehn 123456 (43) smgmshmsrtmh s;s nt;srtn ;nbtugarg '),
('asdfasdfasdf 12345678 (65) asdfag gr 34 6sd 64 fasd fasdfas d fasdfasdf asdf'),
('zxcvzxcvzx34cv zxcvzxcv zxcv zxcv zxcv zcxvz xcv z3 45 xcvzxcz dfg dv df df zfd zdf b 654321 (77)'),
('87654321 (99) n;arng an ; ualerg trhrt srth str sth strh ssth'),
('snhs tgnn ang nu g;arug aegaerlhae s ;5 afnauierhga.ngae489tj 8q3y .sn.5yn b.s n .5hy 5');
Then, the common table expression to get the start index of the 8/6 digit number:
WITH CTE AS
(
SELECT LongText,
PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ([0-9][0-9])%', LongText) As Long,
PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9] ([0-9][0-9])%', LongText) As Short
FROM #T
)
Then, select with a couple of case expressions to extract the number and get the city:
SELECT CASE
WHEN Long > 0 THEN SUBSTRING(LongText, Long, 13)
WHEN Short > 0 THEN SUBSTRING(LongText, Short, 11)
END As Number,
CASE
WHEN Long > 0 THEN 'Paris'
WHEN Short > 0 THEN 'London'
END As City,
LongText
FROM CTE
Results:
Number City LongText
123456 (43) London .njauaerigha n uaer gauer 345 gnaehn 123456 (43) smgmshmsrtmh s;s nt;srtn ;nbtugarg
12345678 (65) Paris asdfasdfasdf 12345678 (65) asdfag gr 34 6sd 64 fasd fasdfas d fasdfasdf asdf
654321 (77) London zxcvzxcvzx34cv zxcvzxcv zxcv zxcv zxcv zcxvz xcv z3 45 xcvzxcz dfg dv df df zfd zdf b 654321 (77)
87654321 (99) Paris 87654321 (99) n;arng an ; ualerg trhrt srth str sth strh ssth
NULL NULL snhs tgnn ang nu g;arug aegaerlhae s ;5 afnauierhga.ngae489tj 8q3y .sn.5yn b.s n .5hy 5
I downloaded database with translations of countries and cities to 70 languages (some of translations are ''), but translations and technical information (populations, flags, territory, phones, etc) about cities\countries saved in the same table.
I mean every translation has its own columns (tranlation itself + description on the language of translation) next to the other info which is not related to translation. Totally about 190 colums, including 70*2 (translation + description).
I don't think this is proper way and I want to move all translations to seperated table keeping FK to main\technical-info table.
So, now I have a table "cities" with the structure like below:
id region_id countries_id phone population lang_1 description_1 lang_2 description_2 lang_3 description_3 .... lang_70 description_70
1 1 1 +7 123 Москва SomeDesc Moscow SomeDesc2 Moskwa SomeText3 Translation70 SomeDesc70
2 1 1 +7 123 Кубинка SomeDesc Kubinka SomeDesc2 Kubinka '' Translation70 SomeDesc70
with 2.5M rows\cities.
I want to move all "lang_(1-70)" and their descriptions to new table "cities_translated" which should look like that:
id cities_id name description lang
1 1 Москва SomeDesc lang_1
2 1 Moscow SomeDesc2 lang_2
3 1 Moskwa SomeText3 lang_3
...
70 1 Translation70 SomeDesc70 lang_70
71 2 Кубинка SomeDesc lang_1
72 2 Kubinka SomeDesc2 lang_2
73 2 Kubinka SomeDesc3 lang_3
...
140 2 Translation70 SomeDesc70 lang_70
Could anyone help me please with proper query to do this transfer?
P.S. I have already a table "languages" and as the next step I will replace all values like 'lang_1', 'lang_2' and so on to proper FK.
Hoped to get raw sql solution in order to improve my sql knowledge, but due to no anwers, i decided to use Python.
initial_table = 'countries.city'
init_table_columns = ['lang_1', 'description_1', 'lang_2', 'description_2', 'lang_3', 'description_3', 'lang_4', 'description_4', 'lang_5', 'description_5', 'lang_6', 'description_6', 'lang_7', 'description_7', 'lang_8', 'description_8', 'lang_9', 'description_9', 'lang_10', 'description_10', 'lang_11', 'description_11', 'lang_12', 'description_12', 'lang_13', 'description_13', 'lang_14', 'description_14', 'lang_15', 'description_15', 'lang_16', 'description_16', 'lang_17', 'description_17', 'lang_18', 'description_18', 'lang_19', 'description_19', 'lang_20', 'description_20', 'lang_21', 'description_21', 'lang_22', 'description_22', 'lang_23', 'description_23', 'lang_24', 'description_24', 'lang_25', 'description_25', 'lang_26', 'description_26', 'lang_27', 'description_27', 'lang_28', 'description_28', 'lang_29', 'description_29', 'lang_30', 'description_30', 'lang_31', 'description_31', 'lang_32', 'description_32', 'lang_33', 'description_33', 'lang_34', 'description_34', 'lang_35', 'description_35', 'lang_36', 'description_36', 'lang_37', 'description_37', 'lang_38', 'description_38', 'lang_39', 'description_39', 'lang_40', 'description_40', 'lang_41', 'description_41', 'lang_42', 'description_42', 'lang_43', 'description_43', 'lang_44', 'description_44', 'lang_45', 'description_45', 'lang_46', 'description_46', 'lang_47', 'description_47', 'lang_48', 'description_48', 'lang_49', 'description_49', 'lang_50', 'description_50', 'lang_51', 'description_51', 'lang_52', 'description_52', 'lang_53', 'description_53', 'lang_54', 'description_54', 'lang_55', 'description_55', 'lang_56', 'description_56', 'lang_57', 'description_57', 'lang_58', 'description_58', 'lang_59', 'description_59', 'lang_60', 'description_60', 'lang_61', 'description_61', 'lang_62', 'description_62', 'lang_63', 'description_63', 'lang_64', 'description_64', 'lang_65', 'description_65', 'lang_66', 'description_66', 'lang_67', 'description_67', 'lang_68', 'description_68', 'lang_69', 'description_69', 'lang_70', 'description_70']
table_translation = 'countries.city_translated'
import psycopg2
import re
conn = psycopg2.connect(database="countries", host='localhost', user="postgres", password="Password")
cur = conn.cursor()
new_cursor = conn.cursor()
cur.execute("""SELECT id FROM %s """ % initial_table)
rows = cur.fetchall()
print("%i rows retrieved" % cur.rowcount)
new_cursor.execute("""BEGIN""")
for row in rows:
print('row:', row)
get_id = row[0]
cur.execute("""SELECT %s FROM %s WHERE id=%s """ % (",".join(init_table_columns), initial_table, get_id))
row_w_info = cur.fetchall()
for i in range(140):
if i%2==0:
name = row_w_info[0][i]
description = row_w_info[0][i+1]
lang_text = init_table_columns[i]
lang_id = int(re.findall(r'\d+', lang_text)[0])
# There are 70 translations, but there is no info what languages are 68, 69, 70
if lang_id >= 68:
lang_id = None
new_cursor.execute("INSERT INTO countries.city_translated (city_id, name, description, lang_id) VALUES (%s, %s, %s, %s)", (get_id, name, description, lang_id))
new_cursor.execute("""COMMIT""")
cur.close()
new_cursor.close()
conn.close()