在 QGIS 中使用 SQL 从 table 获取计数和唯一值列表而不列出每一列

Get count and list of unique values from table without listing each column using SQL in QGIS

基于 SQL to find the number of distinct values in a column and https://gis.stackexchange.com/questions/330932/get-line-length-using-sql-in-qgis

等问题

我看到我们可以使用 SQL 获取唯一值的计数和列表,但我看不到任何可以在不知道字段名称的情况下执行此操作的地方。

在 SQL 中 QGIS 是否可能只允许 these commands? I found this option for another flavor -https://dataedo.com/kb/query/sql-server/list-table-columns-in-database

在 Mapbasic 中,我使用了以下内容,但想在 SQL...

中执行此操作
'Get Column Name list
dim x as integer
dim sColName as string
dim aColName as Alias
For x=1 to TableInfo(temptable, TAB_INFO_NCOLS)
    sColName = ColumnInfo(temptable, "col"+str$(x), COL_INFO_NAME)
    if (sColName not in ("GID","GID_New")) then
        aColName = sColName

        Select aColName, count(*) from temptable group by aColName into "g_"+sColName
        Browse * from "g_"+sColName
        Export "g_"+sColName Into WFolder+RSelection.col2+"_"+sColName+".csv" Type "ASCII" Delimiter "," CharSet "WindowsLatin1" Titles
    End If
Next

我想在 SQL 中我们会使用 http://www.sqlservertutorial.net/sql-server-basics/sql-server-select-distinct/,但我如何告诉它只使用 table 中的每一列而不使用 knowing/specifying 名称?

更新

如果我运行

SELECT DISTINCT * FROM Drainage_Lines_Clip;

我明白了

但我需要类似下面的东西,而不必指定列名。 Ref

它应该看起来像摘自 运行ning Unique on a google sheet 的数据(除了计数)

所以这个答案是基于动态 SQL。你会听到人们说“不要使用它很危险”,但他们是那种认为用户访问系统的最佳方式是 none.. 无论如何。使用动态 SQL 时,请注意 SQL 注入的安全风险。我会把那部分留给你..

下面转到sys.columns table并获取table中的所有列名,然后构造一个SQL语句来计算所有目标中每一列的值 table.

DECLARE @ReturnVar NVARCHAR(MAX);

SELECT @ReturnVar = COALESCE(@ReturnVar + ' UNION ALL ', '') + 'SELECT ''' + c.[name] + ''' [ColumnName], CAST(' + c.[name] + ' AS VARCHAR(MAX)) [ColumnValue], CAST(COUNT(1) AS VARCHAR(MAX)) [Count] FROM dbo.Admissions GROUP BY  CAST(' + c.[name] + ' AS VARCHAR(MAX))'
FROM sys.columns c
INNER JOIN sys.objects o ON o.object_id = c.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE o.[name] = 'Drainage_Lines_Clip'
AND s.[name] = 'dbo'
AND c.[name] != 'GID_New';

EXEC sp_executesql @ReturnVar;

我最终不得不结合使用 PyQGIS 和 SQL 来获得所需的东西。

layer = qgis.utils.iface.activeLayer()
fields=[] # List of fields
Lquery=[] # List of queries to join together with Union All statement
Cquery=[] # Combined Query to use
for field in layer.fields():
    if field.name() not in ('GID_New'):
        fields.append(field.name())
        query = "Select '{0}' as 'Column', {0} as 'Value', count(*) as 'Unique' from {1} group by {0}".format(field.name(), layer.name())
        Lquery.append(query)
    else:
        print (field.name())
#    query = "Select {0}, count(*) from {1} group by {0} order by 2 Desc".format(field.name(), layer.name())

for L in Lquery:
    Cquery.append(L+' Union All ')
query=''.join(map(str, Fquery))
query=query[:-11]+' Order by Column'
vlayer = QgsVectorLayer( "?query={}".format(query), 'counts_'+layer.name(), "virtual" )
QgsProject.instance().addMapLayer(vlayer)