Перейти к содержимому

Как поменять строки местами в sql

  • автор:

Поменять местами столбцы в PostgreSQL 04
16

Обмен столбцами таблицы SQL является частью стандартного репертуара MySQL — это (пока) не поддерживается в PostgreSQL. Хотя официальная вики посвящает проблеме отдельную статью , в ней не показано практического решения, которое также поддерживает представления, индексы и триггеры. Следующий класс выполняет эту работу (как для MySQL, так и для PostgreSQL) либо в командной строке, либо непосредственно в Laravel 5.

 public static function getQuotes() < if (getenv("DB_CONNECTION") == "pgsql") < return ""; >if (getenv("DB_CONNECTION") == "mysql") < return "`"; >> public static function getPath() < if (getenv("DB_CONNECTION") == "pgsql") < $sql = new \PDO('pgsql:host=' . getenv('DB_HOST') . ';port=' . getenv('DB_PORT') . ';dbname=' . getenv('DB_DATABASE') , getenv('DB_USERNAME') , getenv('DB_PASSWORD')); $stmt = $sql->prepare("SHOW data_directory"); $stmt->execute(); $path = str_replace("data", "bin", $stmt->fetchObject()->data_directory) . "/"; > if (getenv("DB_CONNECTION") == "mysql") < $sql = new \PDO('mysql:host=' . getenv('DB_HOST') . ';port=' . getenv('DB_PORT') . ';dbname=' . getenv('DB_DATABASE') , getenv('DB_USERNAME') , getenv('DB_PASSWORD')); $stmt = $sql->prepare("SHOW VARIABLES LIKE 'basedir'"); $stmt->execute(); $path = $stmt->fetchObject()->Value . "bin/"; > return $path; > public static function exportDB() < if (getenv("DB_CONNECTION") == "pgsql") < putenv("PGPASSWORD=" . getenv('DB_PASSWORD')); exec('"' . self::$path . 'pg_dump" --clean --inserts -h ' . getenv('DB_HOST') . ' -p ' . getenv('DB_PORT') . ' -U ' . getenv('DB_USERNAME') . ' ' . getenv('DB_DATABASE') . ' >db.sql'); > if (getenv("DB_CONNECTION") == "mysql") < exec('"' . self::$path . 'mysqldump" -h ' . getenv('DB_HOST') . ' --port ' . getenv('DB_PORT') . ' -u ' . getenv('DB_USERNAME') . ' -p"' . getenv('DB_PASSWORD') . '" ' . getenv('DB_DATABASE') . ' >db.sql'); > return file_get_contents("db.sql"); > public static function importDB($content) < file_put_contents("db.sql", $content); if (getenv("DB_CONNECTION") == "pgsql") < putenv("PGPASSWORD=" . getenv('DB_PASSWORD')); exec('"' . self::$path . 'psql" -h ' . getenv('DB_HOST') . ' -p ' . getenv('DB_PORT') . ' -U ' . getenv('DB_USERNAME') . ' -d ' . getenv('DB_DATABASE') . ' -1 -f db.sql'); >if (getenv("DB_CONNECTION") == "mysql") < exec('"' . self::$path . 'mysql" -h ' . getenv('DB_HOST') . ' --port ' . getenv('DB_PORT') . ' -u ' . getenv('DB_USERNAME') . ' -p"' . getenv('DB_PASSWORD') . '" ' . getenv('DB_DATABASE') . ' --default-character-set=utf8 < db.sql'); >unlink("db.sql"); > public static function getPositions($haystack, $needle) < $positions = []; $lastPos = 0; while (($lastPos = strpos($haystack, $needle, $lastPos)) !== false) < $positions[] = $lastPos; $lastPos = $lastPos + strlen($needle); >return $positions; > public static function getEnd($content, $begin) < $end = $begin; $outside = true; while ($outside !== true || $content[$end] != ";") < if ($content[$end] == "'") < if ($end === 0 || $content[$end - 1] != "\\") < $outside = !$outside; >> $end++; > return ++$end; > public static function splitString($string) < return preg_split('/(?public static function getColumns($query) < $i = 0; $outside = true; $query = self::splitString($query); foreach($query as $i =>$char) < if ($query[$i] == "'") < if ($i === 0 || $query[$i - 1] != "\\") < $outside = !$outside; >> if ($outside === true && $query[$i] == ",") < $query[$i] = "♥"; >$i++; > $query = implode("", $query); $cols = explode("♥", $query); return $cols; > public static function swapNow($table, $col1, $col2, $content) < // loop through relevant statements foreach(["CREATE TABLE " . self::$quotes . $table . self::$quotes, "INSERT INTO " . self::$quotes . $table . self::$quotes] as $skey =>$statement) < $positions = self::getPositions($content, $statement); foreach($positions as $position) < $begin = $position; $end = self::getEnd($content, $begin); $query_all = substr($content, $begin, $end - $begin); $query_inside = substr($query_all, strpos($query_all, "(") + 1, strrpos($query_all, ")") - strpos($query_all, "(") - 1); // get columns $cols = self::getColumns($query_inside); // get relevant column indexes if ($skey == 0) < $col1pos = 0; $col2pos = 0; foreach($cols as $pos =>$col) < $col = trim($col); if (strpos($col, self::$quotes . $col1 . self::$quotes) === 0) < $col1pos = $pos; >if (strpos($col, self::$quotes . $col2 . self::$quotes) === 0) < $col2pos = $pos; >> > // swap columns $tmp = $cols[$col1pos]; $cols[$col1pos] = $cols[$col2pos]; $cols[$col2pos] = $tmp; $query_inside_new = implode(",", $cols); // insert query into content $query_all_new = str_replace($query_inside, $query_inside_new, $query_all); $content = str_replace($query_all, $query_all_new, $content); > > return $content; > > // usage from the command line if (isset($argv) && is_array($argv)) < $args = []; foreach($argv as $key =>$arg) < switch ($arg) < case "-e": $args["engine"] = $argv[$key + 1]; break; case "-h": $args["hostname"] = $argv[$key + 1]; break; case "-P": $args["port"] = $argv[$key + 1]; break; case "-u": $args["username"] = $argv[$key + 1]; break; case "-p": $args["password"] = $argv[$key + 1]; break; case "-d": $args["database"] = $argv[$key + 1]; break; case "-t": $args["table"] = $argv[$key + 1]; break; >> // set default values if (!isset($args["hostname"])) < $args["hostname"] = "127.0.0.1"; >if (!isset($args["port"]) && isset($args["engine"]) && $args["engine"] == "mysql") < $args["port"] = "3306"; >if (!isset($args["port"]) && isset($args["engine"]) && $args["engine"] == "pgsql") < $args["port"] = "5432"; >foreach($args as $option => $arg) < if (!isset($arg)) < die('missing option ' . $option); >> if (count($argv) < 2) < die('error'); >$args["col1"] = $argv[count($argv) - 2]; $args["col2"] = $argv[count($argv) - 1]; putenv("DB_CONNECTION=" . $args["engine"]); putenv("DB_HOST=" . $args["hostname"]); putenv("DB_PORT=" . $args["port"]); putenv("DB_DATABASE=" . $args["database"]); putenv("DB_USERNAME=" . $args["username"]); putenv("DB_PASSWORD=" . $args["password"]); ColumnChanger::swap($args["table"], $args["col1"], $args["col2"]); >

Вызов командной строки не требует пояснений:

php ColumnChanger.php -e pgsql -h 127.0.0.1 -P 5432 -u username -p password -d database -t table col1 col2 php ColumnChanger.php -e mysql -h 127.0.0.1 -P 3306 -u username -p password -d database -t table col1 col2

Интеграция в Laravel 5 также выполняется быстро, просто скопировав ColumnChanger.php в папку app / Helpers. Затем вы можете менять местами столбцы прямо в миграциях.:

 /** * Reverse the migrations. * * @return void */ public function down() < App\Helpers\ColumnChanger::swap("users","password","email"); >>

Адрес офиса

close2 new media GmbH
Auenstrasse 6
80469 Мюнхен

SQL. поменять строки и столбы местами с помощью VIEW

введите сюда описание изображения

Всем привет. Имеется 2 таблицы. Нужно перейти из одной в другую и наоборот. Используя VIEW или виртуальные таблицы. Буду благодарен за совет.

Отслеживать
задан 31 янв 2021 в 19:34
Ponoptikum Ponoptikum
15 3 3 бронзовых знака
А какой диалект?
31 янв 2021 в 19:36
честно, не понял про диалект,
31 янв 2021 в 19:39
но видно, что нужно развернуть таблицу. строки в столбы и наоборот
31 янв 2021 в 19:39
пробую пока через WITH решить, но пока не очень
31 янв 2021 в 19:42
ну вот есть ms-sql, есть mysql, есть oracle, есть postgresql, у вас что?
31 янв 2021 в 19:52

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

select a.student, b.* from result_table_1 a cross join lateral ( values (a.h, 'H'), (a.z, 'Z'), (a.e, 'E') ) as b(atyp, prozent) order by student, atyp; 

Отслеживать
ответ дан 1 фев 2021 в 1:07
Aziz Umarov Aziz Umarov
22.5k 2 2 золотых знака 10 10 серебряных знаков 33 33 бронзовых знака
да, это работает, спасибо
1 фев 2021 в 13:59
@Ponoptikum Ессли ответ помог то можете пометить как полезный под стрелками
1 фев 2021 в 14:06

    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.15.1019

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Поменять строки местами

В одной таблице поменять местами строки
На примере думаю нагляднее будет, что мне надо — вот смотрите есть таблица (NameList) в ней всего 2.

Поменять местами первый и последний столбец, после поменять местами первый и предпоследний строки
Масив 4х4, нужно поменять местами первый и последний столбец, после поменять местами первый и.

У матрицы с размером M*N поменять местами строки с наибольшим и наименьшим элементом местами
Всем привет, подскажите пожалуйста. Как в Windows Form у матрицы с размером M*N поменять местами.

91 / 56 / 12
Регистрация: 02.10.2008
Сообщений: 550
поменять на что? Конкретнее опешите задачу
1312 / 944 / 144
Регистрация: 17.01.2013
Сообщений: 2,348
Регистрация: 07.12.2012
Сообщений: 126
поменять местами строки, если id первичный
63 / 63 / 21
Регистрация: 08.02.2013
Сообщений: 262
Это не таблица, это выборка из 2-ух таблиц
а в выборке порядок меняется с помощью ORDER BY
Регистрация: 07.12.2012
Сообщений: 126
мне сказали что order by не нужно, нужно создать команду при нажатии кнопки два select и два update
2509 / 1130 / 582
Регистрация: 07.06.2014
Сообщений: 3,286

ЦитатаСообщение от Radmir71 Посмотреть сообщение

мне сказали что order by не нужно

я бы на вашем месте этим советчикам не доверял, фигню они Вам советуют.

в реляционных СУБД записи НЕ ИМЕЮТ физического порядка, нельзя сказать, что запись с кодом 1 расположена до записи с кодом 3, например!
И если не использован ORDER BY в запросе, записи МОГУТ быть расположены в ПРОИЗВОЛЬНОМ порядке!
(да, современные мощные СУБД используют внутренние механизмы, которые ЧАЩЕ всего возвращают набор записей в определённом порядке. но поймите, что делать они это НЕ ОБЯЗАНЫ)

Успехов Вам в осознании того факта, что порядок записей в выборке определяется исключетльно через ORDER BY и никак иначе!

Как поменять строки местами в sql

В результате запросо нужно получить:
C R L
1 7 8
Те поменять строки и столбцы местами.

Как сделать такой запрос?


unknown © ( 2006-11-10 15:18 ) [1]

Нормально — никак.
Только подзапросами :
select
(select .. from..) as «C»,
(select .. from..) as «R»,
(select .. from..) as «L»
from .
Если же еще и количество столбцов м.б. не известно
(динамически формируется запрос), то придется
пересмотреть логику.
Если все это для отображения на клиенте — ищи CrossTab
компоненты.


Anatoly Podgoretsky © ( 2006-11-10 15:42 ) [2]

> Kolan (10.11.2006 15:05:00) [0]

Где, в некоторых местах просто, в других надо потрудиться


Desdechado © ( 2006-11-10 16:09 ) [3]

Если это просто для отображения, то искать на королевстве делфи nxdbgrid


Kolan © ( 2006-11-10 19:01 ) [4]

Вот зачем мне это надо:
http://delphimaster.net/view/3-1161622321/

Так вот мне пользователю надо паказывать измерение так:
Номер, Дата, Кто проводил, и параметры в виде R, L, C, Ct и так далее(те в строчку. )


Kolan © ( 2006-11-11 16:07 ) [5]

Так что идей нет? Или это невозможно?


sniknik © ( 2006-11-11 16:55 ) [6]

гдето просто, гдето потрудится. [2].


evvcom © ( 2006-11-13 09:28 ) [7]

> [4] Kolan © (10.11.06 19:01)

Лучше нафиг так не делай. Сделай простейшее дерево и TreeList-ом отображай. В корне

> Номер, Дата, Кто проводил

а в листьях

> параметры в виде R, L, C, Ct и так далее

но для каждого своя строка. Имхо.


Stanislav © ( 2006-11-13 10:39 ) [8]

На MS SQL примерно делается так:

Select
C=Case when name=»C» then max(value) else Null end
R=Case when name=»R» then max(value) else Null end
from table
group by name


Kolan © ( 2006-11-13 12:12 ) [9]

> но для каждого своя строка. Имхо.

Нет это негодится.. Таких записей много. Одна строчка-одно измерение.

> Stanislav © (13.11.06 10:39)

Не очень понял..

Params
MeasurmentID ParamID ParamValue
1 1 10.0
1 2 20.0
1 3 33.0

ParamsDictionary
ParamID ParamName
1 R
2 L
3 C

Вот запрос:
SELECT Params.MeasurmentID, ParamsDictionary.ParamName, Params.ParamValue FROM
Params, ParamsDictionary
WHERE
Params.ParamID = ParamsDictionary.ParamID

Получаю:

№ ParamName Value
1 R 10.0
1 L 20.0
1 C 33.0

А нужно так:
№ R L C
1 10.0 20.0 33.0


Kolan © ( 2006-11-13 12:16 ) [11]

Черт, все испртилось 🙁 Понятно? Или еще раз запостить?


Stanislav © ( 2006-11-13 12:18 ) [12]

Так и будет, если у тебя MS SQL.


Stanislav © ( 2006-11-13 12:20 ) [13]

Только в Group by нужно № поставить.


Kolan © ( 2006-11-13 12:20 ) [14]

> [12] Stanislav © (13.11.06 12:18)
> Так и будет, если у тебя MS SQL.

Это ты T-Sql использовал? Без него никак?

И к тому же тут жестко заданы имена, а их надо выбрать из Словоря.
C=Case when name=«C» then max(value) else Null end


Kolan © ( 2006-11-13 12:25 ) [15]

Попробовал.. Не получилос. Напиши с моими именами полей и таблиц

Я сдела так:
Select
C=Case when name=»C» then max(value) else Null end
R=Case when name=»R» then max(value) else Null end
from Params
group by MeasurmentID

Получил ошибку:
Line 18: Incorrect syntax near «R».


Stanislav © ( 2006-11-13 12:27 ) [16]

Это чистый SQL.
Есть хранимка, но она не работает с большим кол-вом столбцов. если надо опубликую, но там уже T-SQL.
Если Акцесс там встроеный оператор есть.


Stanislav © ( 2006-11-13 12:28 ) [17]

Запятая нужна
C=Case when name=»C» then max(value) else Null end,


Kolan © ( 2006-11-13 12:32 ) [18]

Неполучается 🙁
Запутался. name=»C» — это что за имя? Из какой таблицы?


ЮЮ © ( 2006-11-13 12:33 ) [19]

Ты сам пошел этим путем.
Если в каждом измерении есть R, L, и С, то и стоило их делать атрибутами сущности Измерения.


> А нужно так:
> № R L C
> 1 10.0 20.0 33.0

Тогда забудь о простых запросах:

SELECT
pr.MeasurmentID, pR.Value R, pC.Value C, pL.Value L
FROM
(SELECT * FROM Params WHERE ParamID = 1) pR
LEFT JOIN (SELECT * FROM Params WHERE ParamID = 2) pC ON
pr.MeasurmentID = pC.MeasurmentID
LEFT JOIN (SELECT * FROM Params WHERE ParamID = 3) pL ON
pr.MeasurmentID = pL.MeasurmentID


Kolan © ( 2006-11-13 12:38 ) [20]

> Если в каждом измерении есть R, L, и С, то и стоило их делать
> атрибутами сущности Измерения.

В том все и дело, что параметров — н штук, поэтому и сделал соварь отдельно.

Запрос понял, получилось.. Осталось одно но 🙂
Как сделать для неизвестного числа параметров?


Kolan © ( 2006-11-13 12:39 ) [21]

И к томуже имена опять вручную, а если пользоваетль изменит L на Ln.


ЮЮ © ( 2006-11-13 12:44 ) [22]


> Как сделать для неизвестного числа параметров?

Динамически! Научи программу написать подобный запрос, основываясь на таблице ParamsDictionary


Kolan © ( 2006-11-13 12:47 ) [23]

> [22] ЮЮ © (13.11.06 12:44)
>
> > Как сделать для неизвестного числа параметров?
>
>
> Динамически! Научи программу написать подобный запрос, основываясь
> на таблице ParamsDictionary

Понял. Думал это все база делает 🙂


Stanislav © ( 2006-11-13 13:01 ) [24]

Вот хранимка для динамического построения, честно говоря сам ей не пользуюсь — неудобно, все делаю компонентами отображения.
CREATE PROC sp_CrossW
@table AS sysname,
@onrows AS nvarchar(256),
@onrowsalias AS sysname = NULL,
@oncols AS nvarchar(256),
@sumcol AS sysname = NULL ,
@Condition as nvarchar (256)
AS

DECLARE
@sql AS nvarchar (4000),
@NEWLINE AS char(1)

SET @NEWLINE = CHAR(10)

SET @sql =
«SELECT» + @NEWLINE +
» » + @onrows +
CASE
WHEN @onrowsalias IS NOT NULL THEN » AS » + @onrowsalias
ELSE «»
END
CREATE TABLE #keys(keyvalue nvarchar(100) NOT NULL PRIMARY KEY)

DECLARE @keyssql AS varchar(1000)
SET @keyssql =
«INSERT INTO #keys » +
«SELECT DISTINCT CAST(» +@oncols + » AS nvarchar(100)) » +
«FROM » + @table

DECLARE @key AS nvarchar(100)
SELECT @key = MIN(keyvalue) FROM #keys

WHILE @key IS NOT NULL
BEGIN
SET @sql = @sql + «,» + @NEWLINE +
» MAX(CASE CAST(» + @oncols +
» AS NVARCHAR(100))» + @NEWLINE +
» WHEN N»»» + @key +
«»» THEN » + @sumcol+ @NEWLINE +
» ELSE NULL» + @NEWLINE +
» END) AS [» + @key+»]»

SELECT @key = MIN(keyvalue) FROM #keys
WHERE keyvalue > @key
END

SET @sql = @sql + @NEWLINE +
«FROM » + @table + @NEWLINE +
@condition+@NEWLINE+
«GROUP BY » + @onrows + @NEWLINE +
«ORDER BY » + @onrows

PRINT @sql + @NEWLINE
EXEC (@sql)
GO


Kolan © ( 2006-11-13 13:05 ) [25]

Убил, я еще не дорос до этого 🙁
Лана, пойду у препода спрошу мож он обяснить.

А как ты средаствами отображения это делаешь?


Stanislav © ( 2006-11-13 13:24 ) [26]

Отчеты в Excel Через сводную таблицу.
В FastReport мучатся долго нужно.
А хранимку текст скопируй в QA и выполни, потом вызывать ее так:

sp_CrossW
@table = «MyTable»,
@onrows = «№» — в твоем случае
@oncols = «NAME»
@sumcol = «Value»
@Condition = «where . «, можно «»


atruhin © ( 2006-11-13 15:52 ) [27]

> В FastReport мучатся долго нужно.

Ну ну целый компонент CrossTab на форму кинуть ! 🙂


Stanislav © ( 2006-11-13 16:21 ) [28]

atruhin © (13.11.06 15:52) [27]
Он тормозит, к тому же есть много ограничений.


имя ( 2006-11-13 17:19 ) [29]

Удалено модератором


Alex’ ( 2006-11-14 11:47 ) [30]

В MS SQL 2005 TSQL появились ф-ии PIVOT и UNPIVOT
запрос будет выглядеть примерно:

SELECT [С], [L], [R] FROM MyTable PIVOT (SUM(Value) FOR [Name] IN ([C], [L], [R])) AS PVT

Непроверял, взято http://www.citforum.ru/database/articles/tsql_mssql/


ЮЮ © ( 2006-11-14 12:09 ) [31]

к [19]
Кстати, можно и не join-ить таблицу многократно, а использовать case в select:

SELECT MeasurmentID,
SUM(CASE ParamID WHEN 1 THEN Value ELSE 0 END) AS R,
SUM(CASE ParamID WHEN 2 THEN Value ELSE 0 END) AS C,
SUM(CASE ParamID WHEN 3 THEN Value ELSE 0 END) AS L
FROM Params
GROUP BY MeasurmentID


Stanislav © ( 2006-11-14 14:49 ) [32]

Alex» (14.11.06 11:47) [30]
Классная штука, я использую, только динамически все равно не получиться.


Kolan © ( 2006-11-16 11:47 ) [33]

Это ппц. Справился 🙂 Понадобилось 3 чрон процедуры сделать, создать таблицу и View все динамически.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://kapelnicza.vyvod-iz-zapoya-v-stacionare-samara12.ru/